Linux wireless drivers development
 help / color / mirror / Atom feed
* ADHOC issue with WL12xx driver
From: Błażej Szajrych @ 2013-06-26  6:50 UTC (permalink / raw)
  To: linux-wireless, backports; +Cc: daw, pg

[-- Attachment #1: Type: text/plain, Size: 1735 bytes --]

Hi,

We are encountering serious AD-HOC problems:
.	Commands are run successfully
.	The network is theoretically created
.	It is not visible for other devices and the DMESG show that an error
occurs and the firmware reboots

More info:
.	The box running Linux is the VAR SOM OM44
.	The operation system we are using is Ubuntu 12.04 LTS on the
3.4.0-1490-omap4 kernel. 
.	The processor is in the ARM architecture.
.	WiFi  card: Murata LBEH59XUHC.
.	WiFi driver: wl12xx, wlcore firmware wl127x-fw-5-sr.bin with Rev
6.3.10.0.135.
.	Network connection through the router is working. Network manager is
used to configure the connection.
.	Ad-hoc mode connection is not working - the network is not visible
to other computers.

Commands used to configure the network in adhoc mode are as follows (wlan0
is the WiFi interface name):

1.	Using iw:
.	ifconfig wlan0 down
.	iw wlan0 set type ibss
.	ifconfig wlan0 up
.	iw wlan0 ibss join ADHOC_TEST 2437

2.	Using iwconfig
.	ifconfig wlan0 down 
.	iwconfig wlan0 mode ad-hoc
.	iwconfig wlan0 channel 6
.	iwconfig wlan0 essid ADHOC_TEST
.	ifconfig wlan0 up



Attached you will find the dmesg messages (dmesg.txt).
Using the latest backport of Compat Wireless backports-3.10-rc1-2 did not
help.
Testing with different WiFI dongles gave different results.
TP Link WN725N that uses the Realtek 8192cu driver and is based on the
RTL8188CUS-GR chipset is working correctly in AD-HOC mode.

Could you guide us in anyway in resolving this issue? 

Pozdrawiam, Best Regards,

Błażej Szajrych
Software Developer
+48 669 710 648

Macrix Polska Sp. Z o. o. Sp. K.
ul. Podlaska 15 
PL 60-623 Poznan 
tel.: +48 61 865 47 23 
fax: +48 61 865 47 24


[-- Attachment #2: dmesg.txt --]
[-- Type: text/plain, Size: 7493 bytes --]

[ 5138.270751] ---[ end trace da227214a8249879 ]---
[ 5138.270782] wlcore: ERROR failed to initiate cmd role enable
[ 5138.278594] wlcore: WARNING cmd join failed -110
[ 5138.278625] wlcore: Reading FW panic log
[ 5138.278625] ------------[ cut here ]------------
[ 5138.278686] WARNING: at /home/variscite/Downloads/backports-3.10-rc1-2/drivers/net/wireless/ti/wlcore/cmd.c:63 wlcore_cmd_send_failsafe+0x40/0x3a0 [wlcore]()
[ 5138.278686] Modules linked in: rtl8192c_common(O) rtlwifi(O) 8192cu(O) omapdrm_pvr(O) wl12xx(O) wlcore(O) mac80211(O) cfg80211(O) joydev omapdce(C) rpmsg_omx bnep(O) omaprpc(C) rfcomm(O) omap_remoteproc rpmsg_resmgr_common ppdev remoteproc bluetooth(O) omap_rpmsg_resmgr rpmsg_resmgr virtio_rpmsg_bus lp virtio virtio_ring parport dm_multipath at24 wlcore_sdio(O) compat(O) hid_apple usbhid hid dm_mirror dm_region_hash dm_log btrfs zlib_deflate libcrc32c
[ 5138.278778] [<c001bc38>] (unwind_backtrace+0x0/0xec) from [<c05accd0>] (dump_stack+0x20/0x24)
[ 5138.278808] [<c05accd0>] (dump_stack+0x20/0x24) from [<c00458d4>] (warn_slowpath_common+0x5c/0x74)
[ 5138.278808] [<c00458d4>] (warn_slowpath_common+0x5c/0x74) from [<c0045918>] (warn_slowpath_null+0x2c/0x34)
[ 5138.278839] [<c0045918>] (warn_slowpath_null+0x2c/0x34) from [<bf40c304>] (wlcore_cmd_send_failsafe+0x40/0x3a0 [wlcore])
[ 5138.278900] [<bf40c304>] (wlcore_cmd_send_failsafe+0x40/0x3a0 [wlcore]) from [<bf40c690>] (wl1271_cmd_send+0x2c/0x38 [wlcore])
[ 5138.278930] [<bf40c690>] (wl1271_cmd_send+0x2c/0x38 [wlcore]) from [<bf40edf4>] (wl12xx_cmd_stop_fwlog+0x7c/0xb8 [wlcore])
[ 5138.278991] [<bf40edf4>] (wl12xx_cmd_stop_fwlog+0x7c/0xb8 [wlcore]) from [<bf409908>] (wl1271_recovery_work+0xcc/0x3ac [wlcore])
[ 5138.279022] [<bf409908>] (wl1271_recovery_work+0xcc/0x3ac [wlcore]) from [<c0061d0c>] (process_one_work+0x294/0x48c)
[ 5138.279022] [<c0061d0c>] (process_one_work+0x294/0x48c) from [<c0062214>] (worker_thread+0x144/0x240)
[ 5138.279052] [<c0062214>] (worker_thread+0x144/0x240) from [<c0067090>] (kthread+0x9c/0xa8)
[ 5138.279052] [<c0067090>] (kthread+0x9c/0xa8) from [<c00144a4>] (kernel_thread_exit+0x0/0x8)
[ 5138.279052] ---[ end trace da227214a824987a ]---
[ 5138.279083] ------------[ cut here ]------------
[ 5138.279083] WARNING: at /home/variscite/Downloads/backports-3.10-rc1-2/drivers/net/wireless/ti/wlcore/main.c:790 wl12xx_queue_recovery_work+0x30/0x6c [wlcore]()
[ 5138.279113] Modules linked in: rtl8192c_common(O) rtlwifi(O) 8192cu(O) omapdrm_pvr(O) wl12xx(O) wlcore(O) mac80211(O) cfg80211(O) joydev omapdce(C) rpmsg_omx bnep(O) omaprpc(C) rfcomm(O) omap_remoteproc rpmsg_resmgr_common ppdev remoteproc bluetooth(O) omap_rpmsg_resmgr rpmsg_resmgr virtio_rpmsg_bus lp virtio virtio_ring parport dm_multipath at24 wlcore_sdio(O) compat(O) hid_apple usbhid hid dm_mirror dm_region_hash dm_log btrfs zlib_deflate libcrc32c
[ 5138.279205] [<c001bc38>] (unwind_backtrace+0x0/0xec) from [<c05accd0>] (dump_stack+0x20/0x24)
[ 5138.279205] [<c05accd0>] (dump_stack+0x20/0x24) from [<c00458d4>] (warn_slowpath_common+0x5c/0x74)
[ 5138.279235] [<c00458d4>] (warn_slowpath_common+0x5c/0x74) from [<c0045918>] (warn_slowpath_null+0x2c/0x34)
[ 5138.279266] [<c0045918>] (warn_slowpath_null+0x2c/0x34) from [<bf4093f8>] (wl12xx_queue_recovery_work+0x30/0x6c [wlcore])
[ 5138.279296] [<bf4093f8>] (wl12xx_queue_recovery_work+0x30/0x6c [wlcore]) from [<bf40c644>] (wlcore_cmd_send_failsafe+0x380/0x3a0 [wlcore])
[ 5138.279357] [<bf40c644>] (wlcore_cmd_send_failsafe+0x380/0x3a0 [wlcore]) from [<bf40c690>] (wl1271_cmd_send+0x2c/0x38 [wlcore])
[ 5138.279388] [<bf40c690>] (wl1271_cmd_send+0x2c/0x38 [wlcore]) from [<bf40edf4>] (wl12xx_cmd_stop_fwlog+0x7c/0xb8 [wlcore])
[ 5138.279418] [<bf40edf4>] (wl12xx_cmd_stop_fwlog+0x7c/0xb8 [wlcore]) from [<bf409908>] (wl1271_recovery_work+0xcc/0x3ac [wlcore])
[ 5138.279449] [<bf409908>] (wl1271_recovery_work+0xcc/0x3ac [wlcore]) from [<c0061d0c>] (process_one_work+0x294/0x48c)
[ 5138.279479] [<c0061d0c>] (process_one_work+0x294/0x48c) from [<c0062214>] (worker_thread+0x144/0x240)
[ 5138.279479] [<c0062214>] (worker_thread+0x144/0x240) from [<c0067090>] (kthread+0x9c/0xa8)
[ 5138.279510] [<c0067090>] (kthread+0x9c/0xa8) from [<c00144a4>] (kernel_thread_exit+0x0/0x8)
[ 5138.279510] ---[ end trace da227214a824987b ]---
[ 5138.279510] wlcore: ERROR failed to send stop firmware logger command
[ 5138.289611] wlcore: Hardware recovery in progress. FW ver: Rev 6.3.10.0.133
[ 5138.289916] wlcore: pc: 0x1b6d6, hint_sts: 0x00000000 count: 574
[ 5138.290161] wlcore: down
[ 5138.292236] ieee80211 phy0: Hardware restart was requested
[ 5138.876770] wlcore: firmware booted (Rev 6.3.10.0.133)
[ 5140.889648] wlcore: ERROR command complete timeout
[ 5140.894653] ------------[ cut here ]------------
[ 5140.894714] WARNING: at /home/variscite/Downloads/backports-3.10-rc1-2/drivers/net/wireless/ti/wlcore/main.c:790 wl12xx_queue_recovery_work+0x30/0x6c [wlcore]()
[ 5140.894714] Modules linked in: rtl8192c_common(O) rtlwifi(O) 8192cu(O) omapdrm_pvr(O) wl12xx(O) wlcore(O) mac80211(O) cfg80211(O) joydev omapdce(C) rpmsg_omx bnep(O) omaprpc(C) rfcomm(O) omap_remoteproc rpmsg_resmgr_common ppdev remoteproc bluetooth(O) omap_rpmsg_resmgr rpmsg_resmgr virtio_rpmsg_bus lp virtio virtio_ring parport dm_multipath at24 wlcore_sdio(O) compat(O) hid_apple usbhid hid dm_mirror dm_region_hash dm_log btrfs zlib_deflate libcrc32c
[ 5140.894836] [<c001bc38>] (unwind_backtrace+0x0/0xec) from [<c05accd0>] (dump_stack+0x20/0x24)
[ 5140.894866] [<c05accd0>] (dump_stack+0x20/0x24) from [<c00458d4>] (warn_slowpath_common+0x5c/0x74)
[ 5140.894866] [<c00458d4>] (warn_slowpath_common+0x5c/0x74) from [<c0045918>] (warn_slowpath_null+0x2c/0x34)
[ 5140.894897] [<c0045918>] (warn_slowpath_null+0x2c/0x34) from [<bf4093f8>] (wl12xx_queue_recovery_work+0x30/0x6c [wlcore])
[ 5140.894958] [<bf4093f8>] (wl12xx_queue_recovery_work+0x30/0x6c [wlcore]) from [<bf40c644>] (wlcore_cmd_send_failsafe+0x380/0x3a0 [wlcore])
[ 5140.894989] [<bf40c644>] (wlcore_cmd_send_failsafe+0x380/0x3a0 [wlcore]) from [<bf40c690>] (wl1271_cmd_send+0x2c/0x38 [wlcore])
[ 5140.895050] [<bf40c690>] (wl1271_cmd_send+0x2c/0x38 [wlcore]) from [<bf40d6a0>] (wl12xx_cmd_role_start_ibss+0x174/0x1c8 [wlcore])
[ 5140.895080] [<bf40d6a0>] (wl12xx_cmd_role_start_ibss+0x174/0x1c8 [wlcore]) from [<bf407e88>] (wl1271_op_bss_info_changed+0x834/0xcb4 [wlcore])
[ 5140.895202] [<bf407e88>] (wl1271_op_bss_info_changed+0x834/0xcb4 [wlcore]) from [<bf345be0>] (ieee80211_bss_info_change_notify+0x198/0x240 [mac80211])
[ 5140.895416] [<bf345be0>] (ieee80211_bss_info_change_notify+0x198/0x240 [mac80211]) from [<bf36db98>] (ieee80211_reconfig+0x1630/0x1e18 [mac80211])
[ 5140.895568] [<bf36db98>] (ieee80211_reconfig+0x1630/0x1e18 [mac80211]) from [<bf34518c>] (ieee80211_restart_work+0x80/0x94 [mac80211])
[ 5140.895660] [<bf34518c>] (ieee80211_restart_work+0x80/0x94 [mac80211]) from [<c0061d0c>] (process_one_work+0x294/0x48c)
[ 5140.895690] [<c0061d0c>] (process_one_work+0x294/0x48c) from [<c0062214>] (worker_thread+0x144/0x240)
[ 5140.895690] [<c0062214>] (worker_thread+0x144/0x240) from [<c0067090>] (kthread+0x9c/0xa8)
[ 5140.895721] [<c0067090>] (kthread+0x9c/0xa8) from [<c00144a4>] (kernel_thread_exit+0x0/0x8)
[ 5140.895721] ---[ end trace da227214a824987c ]---
[ 5140.895751] wlcore: ERROR failed to initiate cmd role enable
[ 5140.903717] wlcore: WARNING cmd join failed -110
[ 5140.903778] wlcore: Reading FW panic log

^ permalink raw reply

* Re: [PATCH 2/5] wlcore: use irq_flags in pdata instead of hiding it behing a quirk
From: Tony Lindgren @ 2013-06-26  6:38 UTC (permalink / raw)
  To: Luciano Coelho; +Cc: linux-wireless
In-Reply-To: <1372192406-29430-3-git-send-email-coelho@ti.com>

* Luciano Coelho <coelho@ti.com> [130625 13:39]:
> The platform_quirk element in the platform data was used to change the
> way the IRQ is triggered.  When set, the EDGE_IRQ quirk would change
> the irqflags used and treat edge trigger differently from the rest.
> 
> Instead of hiding this irq flag setting behind the quirk, export the
> whole irq_flags element and let the board file define what to use.
> This will be more meaningful than driver-specific quirks when we
> switch to DT.
> 

Acked-by: Tony Lindgren <tony@atomide.com>

> Cc: Sekhar Nori <nsekhar@ti.com>
> Signed-off-by: Luciano Coelho <coelho@ti.com>

^ permalink raw reply

* Re: [PATCH 1/5] wl1251: split wl251 platform data to a separate structure
From: Tony Lindgren @ 2013-06-26  6:37 UTC (permalink / raw)
  To: Luciano Coelho; +Cc: linux-wireless
In-Reply-To: <1372227318.18889.23.camel@cumari.coelho.fi>

* Luciano Coelho <coelho@ti.com> [130625 23:21]:
> On Tue, 2013-06-25 at 23:33 +0300, Luciano Coelho wrote:
> > Move the wl1251 part of the wl12xx platform data structure into a new
> > structure specifically for wl1251.  Change the platform data built-in
> > block and board files accordingly.
> > 
> > Cc: Tony Lindgren <tony@atomide.com>
> > Signed-off-by: Luciano Coelho <coelho@ti.com>
> > ---
> 
> Hey Tony,
> 
> Is it okay if I send this patch via my tree? There are a couple of tiny
> changes in a couple of OMAP board files...

Yes that's fine, those should not conflict with anything else. For
the arch/arm/*omap* parts:

Acked-by: Tony Lindgren <tony@atomide.com>

^ permalink raw reply

* Re: [PATCH] Documentation: dt: bindings: TI WiLink modules
From: Tony Lindgren @ 2013-06-26  6:24 UTC (permalink / raw)
  To: Luciano Coelho
  Cc: grant.likely, linux-doc, linux-kernel, linux-wireless,
	rob.herring, devicetree-discuss, linux-omap, linux-arm-kernel
In-Reply-To: <1372189024.18889.19.camel@cumari.coelho.fi>

* Luciano Coelho <coelho@ti.com> [130625 12:43]:
> (oh crap, now *really* fixed the ARM mailing list address)
> 
> On Tue, 2013-06-25 at 11:35 +0300, Luciano Coelho wrote:
> > Add device tree bindings documentation for the TI WiLink modules.
> > Currently only the WLAN part of the WiLink6, WiLink7 and WiLink8
> > modules is supported.
> > 
> > Signed-off-by: Luciano Coelho <coelho@ti.com>
> > ---
> > 
> > I created a new directory under net to contain wireless bindings documentation.
> > 
> > The actual implementation in the driver will follow separately.
> > 
> >  .../devicetree/bindings/net/wireless/ti-wilink.txt |   46 ++++++++++++++++++++
> >  1 file changed, 46 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/net/wireless/ti-wilink.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/net/wireless/ti-wilink.txt b/Documentation/devicetree/bindings/net/wireless/ti-wilink.txt
> > new file mode 100644
> > index 0000000..d8e8bfbb
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/net/wireless/ti-wilink.txt
> > @@ -0,0 +1,46 @@
> > +TI WiLink Wireless Modules Device Tree Bindings
> > +===============================================
> > +
> > +The WiLink modules provide wireless connectivity, such as WLAN,
> > +Bluetooth, FM and NFC.
> > +
> > +There are several different modules available, which can be grouped by
> > +their generation: WiLink6, WiLink7 and WiLink8.  WiLink4 is not
> > +currently supported with device tree.
> > +
> > +Currently, only the WLAN portion of the modules is supported with
> > +device tree.
> > +
> > +Required properties:
> > +--------------------
> > +
> > +- compatible: should be "ti,wilink6", "ti,wilink7" or "ti,wilink8"
> > +- interrupt-parent: the interrupt controller
> > +- interrupts: out-of-band WLAN interrupt
> > +	See the interrupt controller's bindings documentation for
> > +	detailed definition.
> > +
> > +Optional properties:
> > +--------------------
> > +
> > +- refclock: the internal WLAN reference clock frequency (required for
> > +  WiLink6 and WiLink7; not used for WiLink8).  Must be one of the
> > +  following:
> > +	0 = 19.2 MHz
> > +	1 = 26.0 MHz
> > +	2 = 38.4 MHz
> > +	3 = 52.0 MHz
> > +	4 = 38.4 MHz, XTAL
> > +	5 = 26.0 MHz, XTAL

This is just the omap refclock, right? If so, you can just pass the
standard clock phandle. I know we don't yet have the DT clocks merged,
but Tero just posted another revision of those.

> > +- tcxoclock: the internal WLAN TCXO clock frequency (required for
> > +  WiLink7 not used for WiLink6 and WiLink8).  Must be one of the
> > +  following:
> > +	0 = 19.200 MHz
> > +	1 = 26.000 MHz
> > +	2 = 38.400 MHz
> > +	3 = 52.000 MHz
> > +	4 = 16.368 MHz
> > +	5 = 32.736 MHz
> > +	6 = 16.800 MHz
> > +	7 = 33.600 MHz

Where does this clock come from? Maybe this can be set based on the
compatible value if it's completely internal?
 
> If this is okay for everyone, can I push this via my tree (which goes to
> linux-wireless->net->linus)? I think it makes more sense to send the
> documentation together with the patch that actually implements the DT
> node parsing in the driver.

If we can use the standard bindings, it might be worth waiting until
we have the DT clocks available as we have the pdata workaround merged
anyways. That's because then we don't need to support the custom
binding later on ;)

Regards,

Tony

^ permalink raw reply

* Re: [PATCH 2/5] wlcore: use irq_flags in pdata instead of hiding it behing a quirk
From: Luciano Coelho @ 2013-06-26  6:17 UTC (permalink / raw)
  To: nsekhar, tony; +Cc: linux-wireless
In-Reply-To: <1372192406-29430-3-git-send-email-coelho@ti.com>

On Tue, 2013-06-25 at 23:33 +0300, Luciano Coelho wrote:
> The platform_quirk element in the platform data was used to change the
> way the IRQ is triggered.  When set, the EDGE_IRQ quirk would change
> the irqflags used and treat edge trigger differently from the rest.
> 
> Instead of hiding this irq flag setting behind the quirk, export the
> whole irq_flags element and let the board file define what to use.
> This will be more meaningful than driver-specific quirks when we
> switch to DT.
> 
> Cc: Tony Lindgren <tony@atomide.com>
> Cc: Sekhar Nori <nsekhar@ti.com>
> Signed-off-by: Luciano Coelho <coelho@ti.com>
> ---

(added Sekhar, forgot to remove my --suppress-cc :P)

Hey Tony and Sekhar,

Another patch with tiny changes in some board files.  Is it okay if I
send it via my tree?

This is part of some clean-up work I did to make the DT implementation
simpler.

--
Cheers,
Luca.

>  arch/arm/mach-davinci/board-da850-evm.c      |    2 +-
>  arch/arm/mach-omap2/board-4430sdp.c          |    1 +
>  arch/arm/mach-omap2/board-omap3evm.c         |    1 +
>  arch/arm/mach-omap2/board-omap4panda.c       |    1 +
>  arch/arm/mach-omap2/board-zoom-peripherals.c |    1 +
>  drivers/net/wireless/ti/wlcore/debugfs.c     |    2 +-
>  drivers/net/wireless/ti/wlcore/main.c        |   13 +++----------
>  drivers/net/wireless/ti/wlcore/wlcore.h      |    5 ++---
>  include/linux/wl12xx.h                       |    5 +----
>  9 files changed, 12 insertions(+), 19 deletions(-)
> 
> diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
> index 8a24b6c..d2a2a98 100644
> --- a/arch/arm/mach-davinci/board-da850-evm.c
> +++ b/arch/arm/mach-davinci/board-da850-evm.c
> @@ -1377,8 +1377,8 @@ static const short da850_wl12xx_pins[] __initconst = {
>  
>  static struct wl12xx_platform_data da850_wl12xx_wlan_data __initdata = {
>  	.irq			= -1,
> +	.irq_flags		= IRQF_TRIGGER_RISING,
>  	.board_ref_clock	= WL12XX_REFCLOCK_38,
> -	.platform_quirks	= WL12XX_PLATFORM_QUIRK_EDGE_IRQ,
>  };
>  
>  static __init int da850_wl12xx_init(void)
> diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
> index 56a9a4f..c2334aa 100644
> --- a/arch/arm/mach-omap2/board-4430sdp.c
> +++ b/arch/arm/mach-omap2/board-4430sdp.c
> @@ -693,6 +693,7 @@ static void __init omap4_sdp4430_wifi_mux_init(void)
>  }
>  
>  static struct wl12xx_platform_data omap4_sdp4430_wlan_data __initdata = {
> +	.irq_flags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
>  	.board_ref_clock = WL12XX_REFCLOCK_26,
>  	.board_tcxo_clock = WL12XX_TCXOCLOCK_26,
>  };
> diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
> index f76d0de..a0c0adf 100644
> --- a/arch/arm/mach-omap2/board-omap3evm.c
> +++ b/arch/arm/mach-omap2/board-omap3evm.c
> @@ -458,6 +458,7 @@ static struct platform_device omap3evm_wlan_regulator = {
>  };
>  
>  struct wl12xx_platform_data omap3evm_wlan_data __initdata = {
> +	.irq_flags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
>  	.board_ref_clock = WL12XX_REFCLOCK_38, /* 38.4 MHz */
>  };
>  #endif
> diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
> index 1e2c75e..ba00862 100644
> --- a/arch/arm/mach-omap2/board-omap4panda.c
> +++ b/arch/arm/mach-omap2/board-omap4panda.c
> @@ -230,6 +230,7 @@ static struct platform_device omap_vwlan_device = {
>  };
>  
>  static struct wl12xx_platform_data omap_panda_wlan_data  __initdata = {
> +	.irq_flags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
>  	.board_ref_clock = WL12XX_REFCLOCK_38, /* 38.4 MHz */
>  };
>  
> diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
> index a90375d..ced012c 100644
> --- a/arch/arm/mach-omap2/board-zoom-peripherals.c
> +++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
> @@ -244,6 +244,7 @@ static struct platform_device *zoom_devices[] __initdata = {
>  };
>  
>  static struct wl12xx_platform_data omap_zoom_wlan_data __initdata = {
> +	.irq_flags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
>  	.board_ref_clock = WL12XX_REFCLOCK_26, /* 26 MHz */
>  };
>  
> diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c
> index c3e1f79..5eff663 100644
> --- a/drivers/net/wireless/ti/wlcore/debugfs.c
> +++ b/drivers/net/wireless/ti/wlcore/debugfs.c
> @@ -486,7 +486,7 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf,
>  	DRIVER_STATE_PRINT_HEX(irq);
>  	/* TODO: ref_clock and tcxo_clock were moved to wl12xx priv */
>  	DRIVER_STATE_PRINT_HEX(hw_pg_ver);
> -	DRIVER_STATE_PRINT_HEX(platform_quirks);
> +	DRIVER_STATE_PRINT_HEX(irq_flags);
>  	DRIVER_STATE_PRINT_HEX(chip.id);
>  	DRIVER_STATE_PRINT_STR(chip.fw_ver_str);
>  	DRIVER_STATE_PRINT_STR(chip.phy_fw_ver_str);
> diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
> index b8db55c..e7294b8 100644
> --- a/drivers/net/wireless/ti/wlcore/main.c
> +++ b/drivers/net/wireless/ti/wlcore/main.c
> @@ -516,7 +516,7 @@ static int wlcore_irq_locked(struct wl1271 *wl)
>  	 * In case edge triggered interrupt must be used, we cannot iterate
>  	 * more than once without introducing race conditions with the hardirq.
>  	 */
> -	if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
> +	if (wl->irq_flags & IRQF_TRIGGER_RISING)
>  		loopcount = 1;
>  
>  	wl1271_debug(DEBUG_IRQ, "IRQ work");
> @@ -5765,7 +5765,6 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size,
>  	wl->ap_ps_map = 0;
>  	wl->ap_fw_ps_map = 0;
>  	wl->quirks = 0;
> -	wl->platform_quirks = 0;
>  	wl->system_hlid = WL12XX_SYSTEM_HLID;
>  	wl->active_sta_count = 0;
>  	wl->active_link_count = 0;
> @@ -5901,7 +5900,6 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
>  	struct platform_device *pdev = wl->pdev;
>  	struct wlcore_platdev_data *pdev_data = pdev->dev.platform_data;
>  	struct wl12xx_platform_data *pdata = pdev_data->pdata;
> -	unsigned long irqflags;
>  	int ret;
>  
>  	if (fw) {
> @@ -5928,16 +5926,11 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
>  	wlcore_adjust_conf(wl);
>  
>  	wl->irq = platform_get_irq(pdev, 0);
> -	wl->platform_quirks = pdata->platform_quirks;
>  	wl->if_ops = pdev_data->if_ops;
> -
> -	if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
> -		irqflags = IRQF_TRIGGER_RISING;
> -	else
> -		irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;
> +	wl->irq_flags = pdata->irq_flags;
>  
>  	ret = request_threaded_irq(wl->irq, NULL, wlcore_irq,
> -				   irqflags, pdev->name, wl);
> +				   wl->irq_flags, pdev->name, wl);
>  	if (ret < 0) {
>  		wl1271_error("request_irq() failed: %d", ret);
>  		goto out_free_nvs;
> diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
> index 0034979..8306bde 100644
> --- a/drivers/net/wireless/ti/wlcore/wlcore.h
> +++ b/drivers/net/wireless/ti/wlcore/wlcore.h
> @@ -185,6 +185,8 @@ struct wl1271 {
>  
>  	int irq;
>  
> +	int irq_flags;
> +
>  	spinlock_t wl_lock;
>  
>  	enum wlcore_state state;
> @@ -384,9 +386,6 @@ struct wl1271 {
>  	/* Quirks of specific hardware revisions */
>  	unsigned int quirks;
>  
> -	/* Platform limitations */
> -	unsigned int platform_quirks;
> -
>  	/* number of currently active RX BA sessions */
>  	int ba_rx_session_count;
>  
> diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h
> index b516b4f..04e3096 100644
> --- a/include/linux/wl12xx.h
> +++ b/include/linux/wl12xx.h
> @@ -57,15 +57,12 @@ struct wl1251_platform_data {
>  
>  struct wl12xx_platform_data {
>  	int irq;
> +	unsigned long irq_flags;
>  	int board_ref_clock;
>  	int board_tcxo_clock;
> -	unsigned long platform_quirks;
>  	bool pwr_in_suspend;
>  };
>  
> -/* Platform does not support level trigger interrupts */
> -#define WL12XX_PLATFORM_QUIRK_EDGE_IRQ	BIT(0)
> -
>  #ifdef CONFIG_WILINK_PLATFORM_DATA
>  
>  int wl12xx_set_platform_data(const struct wl12xx_platform_data *data);



^ permalink raw reply

* Re: [PATCH 1/5] wl1251: split wl251 platform data to a separate structure
From: Luciano Coelho @ 2013-06-26  6:15 UTC (permalink / raw)
  To: tony; +Cc: linux-wireless
In-Reply-To: <1372192406-29430-2-git-send-email-coelho@ti.com>

On Tue, 2013-06-25 at 23:33 +0300, Luciano Coelho wrote:
> Move the wl1251 part of the wl12xx platform data structure into a new
> structure specifically for wl1251.  Change the platform data built-in
> block and board files accordingly.
> 
> Cc: Tony Lindgren <tony@atomide.com>
> Signed-off-by: Luciano Coelho <coelho@ti.com>
> ---

Hey Tony,

Is it okay if I send this patch via my tree? There are a couple of tiny
changes in a couple of OMAP board files...

--
Luca.

>  arch/arm/mach-omap2/board-omap3pandora.c       |    4 +--
>  arch/arm/mach-omap2/board-rx51-peripherals.c   |    2 +-
>  drivers/net/wireless/ti/wilink_platform_data.c |   37 ++++++++++++++++++++----
>  drivers/net/wireless/ti/wl1251/sdio.c          |   12 ++++----
>  drivers/net/wireless/ti/wl1251/spi.c           |    2 +-
>  include/linux/wl12xx.h                         |   22 +++++++++++++-
>  6 files changed, 62 insertions(+), 17 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
> index 28133d5..bf06d95 100644
> --- a/arch/arm/mach-omap2/board-omap3pandora.c
> +++ b/arch/arm/mach-omap2/board-omap3pandora.c
> @@ -540,7 +540,7 @@ static struct spi_board_info omap3pandora_spi_board_info[] __initdata = {
>  
>  static void __init pandora_wl1251_init(void)
>  {
> -	struct wl12xx_platform_data pandora_wl1251_pdata;
> +	struct wl1251_platform_data pandora_wl1251_pdata;
>  	int ret;
>  
>  	memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata));
> @@ -554,7 +554,7 @@ static void __init pandora_wl1251_init(void)
>  		goto fail_irq;
>  
>  	pandora_wl1251_pdata.use_eeprom = true;
> -	ret = wl12xx_set_platform_data(&pandora_wl1251_pdata);
> +	ret = wl1251_set_platform_data(&pandora_wl1251_pdata);
>  	if (ret < 0)
>  		goto fail_irq;
>  
> diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
> index 18ca61e..733f3f2 100644
> --- a/arch/arm/mach-omap2/board-rx51-peripherals.c
> +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
> @@ -80,7 +80,7 @@ enum {
>  	RX51_SPI_MIPID,		/* LCD panel */
>  };
>  
> -static struct wl12xx_platform_data wl1251_pdata;
> +static struct wl1251_platform_data wl1251_pdata;
>  static struct tsc2005_platform_data tsc2005_pdata;
>  
>  #if defined(CONFIG_SENSORS_LIS3_I2C) || defined(CONFIG_SENSORS_LIS3_I2C_MODULE)
> diff --git a/drivers/net/wireless/ti/wilink_platform_data.c b/drivers/net/wireless/ti/wilink_platform_data.c
> index 998e958..a92bd3e 100644
> --- a/drivers/net/wireless/ti/wilink_platform_data.c
> +++ b/drivers/net/wireless/ti/wilink_platform_data.c
> @@ -23,17 +23,17 @@
>  #include <linux/err.h>
>  #include <linux/wl12xx.h>
>  
> -static struct wl12xx_platform_data *platform_data;
> +static struct wl12xx_platform_data *wl12xx_platform_data;
>  
>  int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
>  {
> -	if (platform_data)
> +	if (wl12xx_platform_data)
>  		return -EBUSY;
>  	if (!data)
>  		return -EINVAL;
>  
> -	platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
> -	if (!platform_data)
> +	wl12xx_platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
> +	if (!wl12xx_platform_data)
>  		return -ENOMEM;
>  
>  	return 0;
> @@ -41,9 +41,34 @@ int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
>  
>  struct wl12xx_platform_data *wl12xx_get_platform_data(void)
>  {
> -	if (!platform_data)
> +	if (!wl12xx_platform_data)
>  		return ERR_PTR(-ENODEV);
>  
> -	return platform_data;
> +	return wl12xx_platform_data;
>  }
>  EXPORT_SYMBOL(wl12xx_get_platform_data);
> +
> +static struct wl1251_platform_data *wl1251_platform_data;
> +
> +int __init wl1251_set_platform_data(const struct wl1251_platform_data *data)
> +{
> +	if (wl1251_platform_data)
> +		return -EBUSY;
> +	if (!data)
> +		return -EINVAL;
> +
> +	wl1251_platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
> +	if (!wl1251_platform_data)
> +		return -ENOMEM;
> +
> +	return 0;
> +}
> +
> +struct wl1251_platform_data *wl1251_get_platform_data(void)
> +{
> +	if (!wl1251_platform_data)
> +		return ERR_PTR(-ENODEV);
> +
> +	return wl1251_platform_data;
> +}
> +EXPORT_SYMBOL(wl1251_get_platform_data);
> diff --git a/drivers/net/wireless/ti/wl1251/sdio.c b/drivers/net/wireless/ti/wl1251/sdio.c
> index e2b3d9c..b75a37a 100644
> --- a/drivers/net/wireless/ti/wl1251/sdio.c
> +++ b/drivers/net/wireless/ti/wl1251/sdio.c
> @@ -227,7 +227,7 @@ static int wl1251_sdio_probe(struct sdio_func *func,
>  	struct wl1251 *wl;
>  	struct ieee80211_hw *hw;
>  	struct wl1251_sdio *wl_sdio;
> -	const struct wl12xx_platform_data *wl12xx_board_data;
> +	const struct wl1251_platform_data *wl1251_board_data;
>  
>  	hw = wl1251_alloc_hw();
>  	if (IS_ERR(hw))
> @@ -254,11 +254,11 @@ static int wl1251_sdio_probe(struct sdio_func *func,
>  	wl->if_priv = wl_sdio;
>  	wl->if_ops = &wl1251_sdio_ops;
>  
> -	wl12xx_board_data = wl12xx_get_platform_data();
> -	if (!IS_ERR(wl12xx_board_data)) {
> -		wl->set_power = wl12xx_board_data->set_power;
> -		wl->irq = wl12xx_board_data->irq;
> -		wl->use_eeprom = wl12xx_board_data->use_eeprom;
> +	wl1251_board_data = wl1251_get_platform_data();
> +	if (!IS_ERR(wl1251_board_data)) {
> +		wl->set_power = wl1251_board_data->set_power;
> +		wl->irq = wl1251_board_data->irq;
> +		wl->use_eeprom = wl1251_board_data->use_eeprom;
>  	}
>  
>  	if (wl->irq) {
> diff --git a/drivers/net/wireless/ti/wl1251/spi.c b/drivers/net/wireless/ti/wl1251/spi.c
> index c7dc6fe..6bbbfe6 100644
> --- a/drivers/net/wireless/ti/wl1251/spi.c
> +++ b/drivers/net/wireless/ti/wl1251/spi.c
> @@ -238,7 +238,7 @@ static const struct wl1251_if_operations wl1251_spi_ops = {
>  
>  static int wl1251_spi_probe(struct spi_device *spi)
>  {
> -	struct wl12xx_platform_data *pdata;
> +	struct wl1251_platform_data *pdata;
>  	struct ieee80211_hw *hw;
>  	struct wl1251 *wl;
>  	int ret;
> diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h
> index a54fe82..b516b4f 100644
> --- a/include/linux/wl12xx.h
> +++ b/include/linux/wl12xx.h
> @@ -48,11 +48,15 @@ enum {
>  	WL12XX_TCXOCLOCK_33_6	= 7, /* 33.6 MHz */
>  };
>  
> -struct wl12xx_platform_data {
> +struct wl1251_platform_data {
>  	void (*set_power)(bool enable);
>  	/* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */
>  	int irq;
>  	bool use_eeprom;
> +};
> +
> +struct wl12xx_platform_data {
> +	int irq;
>  	int board_ref_clock;
>  	int board_tcxo_clock;
>  	unsigned long platform_quirks;
> @@ -68,6 +72,10 @@ int wl12xx_set_platform_data(const struct wl12xx_platform_data *data);
>  
>  struct wl12xx_platform_data *wl12xx_get_platform_data(void);
>  
> +int wl1251_set_platform_data(const struct wl1251_platform_data *data);
> +
> +struct wl1251_platform_data *wl1251_get_platform_data(void);
> +
>  #else
>  
>  static inline
> @@ -82,6 +90,18 @@ struct wl12xx_platform_data *wl12xx_get_platform_data(void)
>  	return ERR_PTR(-ENODATA);
>  }
>  
> +static inline
> +int wl1251_set_platform_data(const struct wl1251_platform_data *data)
> +{
> +	return -ENOSYS;
> +}
> +
> +static inline
> +struct wl1251_platform_data *wl1251_get_platform_data(void)
> +{
> +	return ERR_PTR(-ENODATA);
> +}
> +
>  #endif
>  
>  #endif



^ permalink raw reply

* [PATCH v4 1/2] cfg80211/nl80211: rename packet pattern related structures and enums
From: Bing Zhao @ 2013-06-26  2:03 UTC (permalink / raw)
  To: linux-wireless
  Cc: Johannes Berg, Luis R. Rodriguez, Jouni Malinen,
	Vasanthakumar Thiagarajan, Senthil Balasubramanian,
	Luciano Coelho, Amitkumar Karwar, Bing Zhao

From: Amitkumar Karwar <akarwar@marvell.com>

Currently packet patterns and it's enum/structures are used only
for WoWLAN feature. As we intend to reuse them for new feature
packet coalesce, they are renamed in this patch.

Older names are kept for backward compatibility purpose.

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
v2: more details about the renames in commit log (Luis R. Rodriguez)
    don't break the API with existing applications (Johannes Berg)
v3: __NL80211_PKTPAT_INVALID (Johannes Berg)
v4: similar to wowlan, take coalesce support information out of
    wiphy structure so that we don't need to allocate the space for
    devices which don't advertise the feature. (Johannes Berg)

 drivers/net/wireless/ath/ath9k/main.c   |  2 +-
 drivers/net/wireless/mwifiex/cfg80211.c |  3 +--
 drivers/net/wireless/ti/wlcore/main.c   | 10 ++++----
 include/net/cfg80211.h                  |  6 ++---
 include/uapi/linux/nl80211.h            | 45 ++++++++++++++++++++-------------
 net/wireless/nl80211.c                  | 34 ++++++++++++-------------
 6 files changed, 53 insertions(+), 47 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index cc5a98b..d1ce3da 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2098,7 +2098,7 @@ static void ath9k_wow_add_pattern(struct ath_softc *sc,
 {
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath9k_wow_pattern *wow_pattern = NULL;
-	struct cfg80211_wowlan_trig_pkt_pattern *patterns = wowlan->patterns;
+	struct cfg80211_pkt_pattern *patterns = wowlan->patterns;
 	int mask_len;
 	s8 i = 0;
 
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 856aea2..aa7e66f 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -2295,8 +2295,7 @@ EXPORT_SYMBOL_GPL(mwifiex_del_virtual_intf);
 
 #ifdef CONFIG_PM
 static bool
-mwifiex_is_pattern_supported(struct cfg80211_wowlan_trig_pkt_pattern *pat,
-			     s8 *byte_seq)
+mwifiex_is_pattern_supported(struct cfg80211_pkt_pattern *pat, s8 *byte_seq)
 {
 	int j, k, valid_byte_cnt = 0;
 	bool dont_care_byte = false;
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 796928b..d89d58a 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -1328,7 +1328,7 @@ static struct sk_buff *wl12xx_alloc_dummy_packet(struct wl1271 *wl)
 
 #ifdef CONFIG_PM
 static int
-wl1271_validate_wowlan_pattern(struct cfg80211_wowlan_trig_pkt_pattern *p)
+wl1271_validate_wowlan_pattern(struct cfg80211_pkt_pattern *p)
 {
 	int num_fields = 0, in_field = 0, fields_size = 0;
 	int i, pattern_len = 0;
@@ -1471,9 +1471,9 @@ void wl1271_rx_filter_flatten_fields(struct wl12xx_rx_filter *filter,
  * Allocates an RX filter returned through f
  * which needs to be freed using rx_filter_free()
  */
-static int wl1271_convert_wowlan_pattern_to_rx_filter(
-	struct cfg80211_wowlan_trig_pkt_pattern *p,
-	struct wl12xx_rx_filter **f)
+static int
+wl1271_convert_wowlan_pattern_to_rx_filter(struct cfg80211_pkt_pattern *p,
+					   struct wl12xx_rx_filter **f)
 {
 	int i, j, ret = 0;
 	struct wl12xx_rx_filter *filter;
@@ -1575,7 +1575,7 @@ static int wl1271_configure_wowlan(struct wl1271 *wl,
 
 	/* Translate WoWLAN patterns into filters */
 	for (i = 0; i < wow->n_patterns; i++) {
-		struct cfg80211_wowlan_trig_pkt_pattern *p;
+		struct cfg80211_pkt_pattern *p;
 		struct wl12xx_rx_filter *filter = NULL;
 
 		p = &wow->patterns[i];
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 7b0730a..207b079 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1698,7 +1698,7 @@ struct cfg80211_pmksa {
 };
 
 /**
- * struct cfg80211_wowlan_trig_pkt_pattern - packet pattern
+ * struct cfg80211_pkt_pattern - packet pattern
  * @mask: bitmask where to match pattern and where to ignore bytes,
  *	one bit per byte, in same format as nl80211
  * @pattern: bytes to match where bitmask is 1
@@ -1708,7 +1708,7 @@ struct cfg80211_pmksa {
  * Internal note: @mask and @pattern are allocated in one chunk of
  * memory, free @mask only!
  */
-struct cfg80211_wowlan_trig_pkt_pattern {
+struct cfg80211_pkt_pattern {
 	u8 *mask, *pattern;
 	int pattern_len;
 	int pkt_offset;
@@ -1770,7 +1770,7 @@ struct cfg80211_wowlan {
 	bool any, disconnect, magic_pkt, gtk_rekey_failure,
 	     eap_identity_req, four_way_handshake,
 	     rfkill_release;
-	struct cfg80211_wowlan_trig_pkt_pattern *patterns;
+	struct cfg80211_pkt_pattern *patterns;
 	struct cfg80211_wowlan_tcp *tcp;
 	int n_patterns;
 };
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 861e5eb..de0ce80 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -3060,11 +3060,11 @@ enum nl80211_tx_power_setting {
 };
 
 /**
- * enum nl80211_wowlan_packet_pattern_attr - WoWLAN packet pattern attribute
- * @__NL80211_WOWLAN_PKTPAT_INVALID: invalid number for nested attribute
- * @NL80211_WOWLAN_PKTPAT_PATTERN: the pattern, values where the mask has
+ * enum nl80211_packet_pattern_attr - packet pattern attribute
+ * @__NL80211_PKTPAT_INVALID: invalid number for nested attribute
+ * @NL80211_PKTPAT_PATTERN: the pattern, values where the mask has
  *	a zero bit are ignored
- * @NL80211_WOWLAN_PKTPAT_MASK: pattern mask, must be long enough to have
+ * @NL80211_PKTPAT_MASK: pattern mask, must be long enough to have
  *	a bit for each byte in the pattern. The lowest-order bit corresponds
  *	to the first byte of the pattern, but the bytes of the pattern are
  *	in a little-endian-like format, i.e. the 9th byte of the pattern
@@ -3075,23 +3075,23 @@ enum nl80211_tx_power_setting {
  *	Note that the pattern matching is done as though frames were not
  *	802.11 frames but 802.3 frames, i.e. the frame is fully unpacked
  *	first (including SNAP header unpacking) and then matched.
- * @NL80211_WOWLAN_PKTPAT_OFFSET: packet offset, pattern is matched after
+ * @NL80211_PKTPAT_OFFSET: packet offset, pattern is matched after
  *	these fixed number of bytes of received packet
- * @NUM_NL80211_WOWLAN_PKTPAT: number of attributes
- * @MAX_NL80211_WOWLAN_PKTPAT: max attribute number
+ * @NUM_NL80211_PKTPAT: number of attributes
+ * @MAX_NL80211_PKTPAT: max attribute number
  */
-enum nl80211_wowlan_packet_pattern_attr {
-	__NL80211_WOWLAN_PKTPAT_INVALID,
-	NL80211_WOWLAN_PKTPAT_MASK,
-	NL80211_WOWLAN_PKTPAT_PATTERN,
-	NL80211_WOWLAN_PKTPAT_OFFSET,
+enum nl80211_packet_pattern_attr {
+	__NL80211_PKTPAT_INVALID,
+	NL80211_PKTPAT_MASK,
+	NL80211_PKTPAT_PATTERN,
+	NL80211_PKTPAT_OFFSET,
 
-	NUM_NL80211_WOWLAN_PKTPAT,
-	MAX_NL80211_WOWLAN_PKTPAT = NUM_NL80211_WOWLAN_PKTPAT - 1,
+	NUM_NL80211_PKTPAT,
+	MAX_NL80211_PKTPAT = NUM_NL80211_PKTPAT - 1,
 };
 
 /**
- * struct nl80211_wowlan_pattern_support - pattern support information
+ * struct nl80211_pattern_support - packet pattern support information
  * @max_patterns: maximum number of patterns supported
  * @min_pattern_len: minimum length of each pattern
  * @max_pattern_len: maximum length of each pattern
@@ -3101,13 +3101,22 @@ enum nl80211_wowlan_packet_pattern_attr {
  * that is part of %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED in the
  * capability information given by the kernel to userspace.
  */
-struct nl80211_wowlan_pattern_support {
+struct nl80211_pattern_support {
 	__u32 max_patterns;
 	__u32 min_pattern_len;
 	__u32 max_pattern_len;
 	__u32 max_pkt_offset;
 } __attribute__((packed));
 
+/* only for backward compatibility */
+#define __NL80211_WOWLAN_PKTPAT_INVALID __NL80211_PKTPAT_INVALID
+#define NL80211_WOWLAN_PKTPAT_MASK NL80211_PKTPAT_MASK
+#define NL80211_WOWLAN_PKTPAT_PATTERN NL80211_PKTPAT_PATTERN
+#define NL80211_WOWLAN_PKTPAT_OFFSET NL80211_PKTPAT_OFFSET
+#define NUM_NL80211_WOWLAN_PKTPAT NUM_NL80211_PKTPAT
+#define MAX_NL80211_WOWLAN_PKTPAT MAX_NL80211_PKTPAT
+#define nl80211_wowlan_pattern_support nl80211_pattern_support
+
 /**
  * enum nl80211_wowlan_triggers - WoWLAN trigger definitions
  * @__NL80211_WOWLAN_TRIG_INVALID: invalid number for nested attributes
@@ -3127,7 +3136,7 @@ struct nl80211_wowlan_pattern_support {
  *	pattern matching is done after the packet is converted to the MSDU.
  *
  *	In %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED, it is a binary attribute
- *	carrying a &struct nl80211_wowlan_pattern_support.
+ *	carrying a &struct nl80211_pattern_support.
  *
  *	When reporting wakeup. it is a u32 attribute containing the 0-based
  *	index of the pattern that caused the wakeup, in the patterns passed
@@ -3284,7 +3293,7 @@ struct nl80211_wowlan_tcp_data_token_feature {
  * @NL80211_WOWLAN_TCP_WAKE_PAYLOAD: wake packet payload, for advertising a
  *	u32 attribute holding the maximum length
  * @NL80211_WOWLAN_TCP_WAKE_MASK: Wake packet payload mask, not used for
- *	feature advertising. The mask works like @NL80211_WOWLAN_PKTPAT_MASK
+ *	feature advertising. The mask works like @NL80211_PKTPAT_MASK
  *	but on the TCP payload only.
  * @NUM_NL80211_WOWLAN_TCP: number of TCP attributes
  * @MAX_NL80211_WOWLAN_TCP: highest attribute number
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index bed6af5..785761f 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -974,7 +974,7 @@ static int nl80211_send_wowlan(struct sk_buff *msg,
 		return -ENOBUFS;
 
 	if (dev->wiphy.wowlan->n_patterns) {
-		struct nl80211_wowlan_pattern_support pat = {
+		struct nl80211_pattern_support pat = {
 			.max_patterns = dev->wiphy.wowlan->n_patterns,
 			.min_pattern_len = dev->wiphy.wowlan->pattern_min_len,
 			.max_pattern_len = dev->wiphy.wowlan->pattern_max_len,
@@ -7591,12 +7591,11 @@ static int nl80211_send_wowlan_patterns(struct sk_buff *msg,
 		if (!nl_pat)
 			return -ENOBUFS;
 		pat_len = wowlan->patterns[i].pattern_len;
-		if (nla_put(msg, NL80211_WOWLAN_PKTPAT_MASK,
-			    DIV_ROUND_UP(pat_len, 8),
+		if (nla_put(msg, NL80211_PKTPAT_MASK, DIV_ROUND_UP(pat_len, 8),
 			    wowlan->patterns[i].mask) ||
-		    nla_put(msg, NL80211_WOWLAN_PKTPAT_PATTERN,
-			    pat_len, wowlan->patterns[i].pattern) ||
-		    nla_put_u32(msg, NL80211_WOWLAN_PKTPAT_OFFSET,
+		    nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
+			    wowlan->patterns[i].pattern) ||
+		    nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
 				wowlan->patterns[i].pkt_offset))
 			return -ENOBUFS;
 		nla_nest_end(msg, nl_pat);
@@ -7937,7 +7936,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
 		struct nlattr *pat;
 		int n_patterns = 0;
 		int rem, pat_len, mask_len, pkt_offset;
-		struct nlattr *pat_tb[NUM_NL80211_WOWLAN_PKTPAT];
+		struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
 
 		nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
 				    rem)
@@ -7956,26 +7955,25 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
 
 		nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
 				    rem) {
-			nla_parse(pat_tb, MAX_NL80211_WOWLAN_PKTPAT,
-				  nla_data(pat), nla_len(pat), NULL);
+			nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat),
+				  nla_len(pat), NULL);
 			err = -EINVAL;
-			if (!pat_tb[NL80211_WOWLAN_PKTPAT_MASK] ||
-			    !pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN])
+			if (!pat_tb[NL80211_PKTPAT_MASK] ||
+			    !pat_tb[NL80211_PKTPAT_PATTERN])
 				goto error;
-			pat_len = nla_len(pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN]);
+			pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
 			mask_len = DIV_ROUND_UP(pat_len, 8);
-			if (nla_len(pat_tb[NL80211_WOWLAN_PKTPAT_MASK]) !=
-			    mask_len)
+			if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
 				goto error;
 			if (pat_len > wowlan->pattern_max_len ||
 			    pat_len < wowlan->pattern_min_len)
 				goto error;
 
-			if (!pat_tb[NL80211_WOWLAN_PKTPAT_OFFSET])
+			if (!pat_tb[NL80211_PKTPAT_OFFSET])
 				pkt_offset = 0;
 			else
 				pkt_offset = nla_get_u32(
-					pat_tb[NL80211_WOWLAN_PKTPAT_OFFSET]);
+					pat_tb[NL80211_PKTPAT_OFFSET]);
 			if (pkt_offset > wowlan->max_pkt_offset)
 				goto error;
 			new_triggers.patterns[i].pkt_offset = pkt_offset;
@@ -7989,11 +7987,11 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
 			new_triggers.patterns[i].pattern =
 				new_triggers.patterns[i].mask + mask_len;
 			memcpy(new_triggers.patterns[i].mask,
-			       nla_data(pat_tb[NL80211_WOWLAN_PKTPAT_MASK]),
+			       nla_data(pat_tb[NL80211_PKTPAT_MASK]),
 			       mask_len);
 			new_triggers.patterns[i].pattern_len = pat_len;
 			memcpy(new_triggers.patterns[i].pattern,
-			       nla_data(pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN]),
+			       nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
 			       pat_len);
 			i++;
 		}
-- 
1.8.0


^ permalink raw reply related

* [PATCH v4 2/2] cfg80211/nl80211: Add packet coalesce support
From: Bing Zhao @ 2013-06-26  2:03 UTC (permalink / raw)
  To: linux-wireless
  Cc: Johannes Berg, Luis R. Rodriguez, Jouni Malinen,
	Vasanthakumar Thiagarajan, Senthil Balasubramanian,
	Luciano Coelho, Amitkumar Karwar, Bing Zhao
In-Reply-To: <1372212237-5687-1-git-send-email-bzhao@marvell.com>

From: Amitkumar Karwar <akarwar@marvell.com>

In most cases, host that receives IPv4 and IPv6 multicast/broadcast
packets does not do anything with these packets. Therefore the
reception of these unwanted packets causes unnecessary processing
and power consumption.

Packet coalesce feature helps to reduce number of received
interrupts to host by buffering these packets in firmware/hardware
for some predefined time. Received interrupt will be generated when
one of the following events occur.
a) Expiration of hardware timer whose expiration time is set to
maximum coalescing delay of matching coalesce rule.
b) Coalescing buffer in hardware reaches it's limit.
c) Packet doesn't match any of the configured coalesce rules.

This patch adds set/get configuration support for packet coalesce.
User needs to configure following parameters for creating a coalesce
rule.
a) Maximum coalescing delay
b) List of packet patterns which needs to be matched
c) Condition for coalescence. pattern 'match' or 'no match'
Multiple such rules can be created.

This feature needs to be advertised during driver initialization.
Drivers are supposed to do required firmware/hardware settings based
on user configuration.

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
v2: add documentation in nl80211.h and elabiration of "coalesce"
    in commit log (Luis R. Rodriguez)
v3: address comments (Johannes Berg):
    use enum variable for 'condition';
    remove new feature flag;
    remove spurious;
    update documentation
v4: similar to wowlan, take coalesce support information out of
    wiphy structure so that we don't need to allocate the space for
    devices which don't advertise the feature. (Johannes Berg)
    set/clear coalesce rules through configuration file. (Johannes Berg)

 include/net/cfg80211.h       |  51 ++++++++
 include/uapi/linux/nl80211.h |  89 ++++++++++++-
 net/wireless/core.c          |  11 ++
 net/wireless/core.h          |   2 +
 net/wireless/nl80211.c       | 293 +++++++++++++++++++++++++++++++++++++++++++
 net/wireless/nl80211.h       |   2 +
 6 files changed, 446 insertions(+), 2 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 207b079..ad61475 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1776,6 +1776,35 @@ struct cfg80211_wowlan {
 };
 
 /**
+ * struct cfg80211_coalesce_rules - Coalesce rule parameters
+ *
+ * This structure defines coalesce rule for the device.
+ * @delay: maximum coalescing delay in msecs.
+ * @condition: condition for packet coalescence.
+ *	see &enum nl80211_coalesce_condition.
+ * @patterns: array of packet patterns
+ * @n_patterns: number of patterns
+ */
+struct cfg80211_coalesce_rules {
+	int delay;
+	enum nl80211_coalesce_condition condition;
+	struct cfg80211_pkt_pattern *patterns;
+	int n_patterns;
+};
+
+/**
+ * struct cfg80211_coalesce - Packet coalescing settings
+ *
+ * This structure defines coalescing settings.
+ * @rules: array of coalesce rules
+ * @n_rules: number of rules
+ */
+struct cfg80211_coalesce {
+	struct cfg80211_coalesce_rules **rules;
+	int n_rules;
+};
+
+/**
  * struct cfg80211_wowlan_wakeup - wakeup report
  * @disconnect: woke up by getting disconnected
  * @magic_pkt: woke up by receiving magic packet
@@ -2071,6 +2100,7 @@ struct cfg80211_update_ft_ies_params {
  *	driver can take the most appropriate actions.
  * @crit_proto_stop: Indicates critical protocol no longer needs increased link
  *	reliability. This operation can not fail.
+ * @set_coalesce: Set coalesce parameters.
  */
 struct cfg80211_ops {
 	int	(*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -2306,6 +2336,8 @@ struct cfg80211_ops {
 				    u16 duration);
 	void	(*crit_proto_stop)(struct wiphy *wiphy,
 				   struct wireless_dev *wdev);
+	int	(*set_coalesce)(struct wiphy *wiphy,
+				struct cfg80211_coalesce *coalesce);
 };
 
 /*
@@ -2532,6 +2564,23 @@ struct wiphy_wowlan_support {
 };
 
 /**
+ * struct wiphy_coalesce_support - coalesce support data
+ * @n_rules: maximum number of coalesce rules
+ * @n_patterns: number of supported patterns
+ *	(see nl80211.h for the pattern definition)
+ * @pattern_max_len: maximum length of each pattern
+ * @pattern_min_len: minimum length of each pattern
+ * @max_pkt_offset: maximum Rx packet offset
+ */
+struct wiphy_coalesce_support {
+	int n_rules;
+	int n_patterns;
+	int pattern_max_len;
+	int pattern_min_len;
+	int max_pkt_offset;
+};
+
+/**
  * struct wiphy - wireless hardware description
  * @reg_notifier: the driver's regulatory notification callback,
  *	note that if your driver uses wiphy_apply_custom_regulatory()
@@ -2641,6 +2690,7 @@ struct wiphy_wowlan_support {
  *	802.11-2012 8.4.2.29 for the defined fields.
  * @extended_capabilities_mask: mask of the valid values
  * @extended_capabilities_len: length of the extended capabilities
+ * @wiphy_coalesce_support coalesce: coalesce support information
  */
 struct wiphy {
 	/* assign these fields before you register the wiphy */
@@ -2750,6 +2800,7 @@ struct wiphy {
 	const struct iw_handler_def *wext;
 #endif
 
+	const struct wiphy_coalesce_support *coalesce;
 	char priv[0] __aligned(NETDEV_ALIGN);
 };
 
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index de0ce80..fb5bbad 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -126,6 +126,31 @@
  */
 
 /**
+ * DOC: packet coalesce support
+ *
+ * In most cases, host that receives IPv4 and IPv6 multicast/broadcast
+ * packets does not do anything with these packets. Therefore the
+ * reception of these unwanted packets causes unnecessary processing
+ * and power consumption.
+ *
+ * Packet coalesce feature helps to reduce number of received interrupts
+ * to host by buffering these packets in firmware/hardware for some
+ * predefined time. Received interrupt will be generated when one of the
+ * following events occur.
+ * a) Expiration of hardware timer whose expiration time is set to maximum
+ * coalescing delay of matching coalesce rule.
+ * b) Coalescing buffer in hardware reaches it's limit.
+ * c) Packet doesn't match any of the configured coalesce rules.
+ *
+ * User needs to configure following parameters for creating a coalesce
+ * rule.
+ * a) Maximum coalescing delay
+ * b) List of packet patterns which needs to be matched
+ * c) Condition for coalescence. pattern 'match' or 'no match'
+ * Multiple such rules can be created.
+ */
+
+/**
  * enum nl80211_commands - supported nl80211 commands
  *
  * @NL80211_CMD_UNSPEC: unspecified command to catch errors
@@ -648,6 +673,10 @@
  * @NL80211_CMD_CRIT_PROTOCOL_STOP: Indicates the connection reliability can
  *	return back to normal.
  *
+ * @NL80211_CMD_GET_COALESCE: Get currently supported coalesce rules.
+ *
+ * @NL80211_CMD_SET_COALESCE: Configure coalesce rules or clear existing rules.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -810,6 +839,9 @@ enum nl80211_commands {
 	NL80211_CMD_CRIT_PROTOCOL_START,
 	NL80211_CMD_CRIT_PROTOCOL_STOP,
 
+	NL80211_CMD_GET_COALESCE,
+	NL80211_CMD_SET_COALESCE,
+
 	/* add new commands above here */
 
 	/* used to define NL80211_CMD_MAX below */
@@ -1436,6 +1468,8 @@ enum nl80211_commands {
  *	allowed to be used with the first @NL80211_CMD_SET_STATION command to
  *	update a TDLS peer STA entry.
  *
+ * @NL80211_ATTR_COALESCE_RULE: Coalesce rule information.
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -1736,6 +1770,8 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_PEER_AID,
 
+	NL80211_ATTR_COALESCE_RULE,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -3098,8 +3134,10 @@ enum nl80211_packet_pattern_attr {
  * @max_pkt_offset: maximum Rx packet offset
  *
  * This struct is carried in %NL80211_WOWLAN_TRIG_PKT_PATTERN when
- * that is part of %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED in the
- * capability information given by the kernel to userspace.
+ * that is part of %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED or in
+ * %NL80211_ATTR_COALESCE_RULE_PKT_PATTERN when that is part of
+ * %NL80211_ATTR_COALESCE_RULE in the capability information given
+ * by the kernel to userspace.
  */
 struct nl80211_pattern_support {
 	__u32 max_patterns;
@@ -3318,6 +3356,53 @@ enum nl80211_wowlan_tcp_attrs {
 };
 
 /**
+ * struct nl80211_coalesce_rule_support - coalesce rule support information
+ * @max_rules: maximum number of rules supported
+ * @pat: packet pattern support information
+ *
+ * This struct is carried in %NL80211_ATTR_COALESCE_RULE in the
+ * capability information given by the kernel to userspace.
+ */
+struct nl80211_coalesce_rule_support {
+	__u32 max_rules;
+	struct nl80211_pattern_support pat;
+} __attribute__((packed));
+
+/**
+ * enum nl80211_attr_coalesce_rule - coalesce rule attribute
+ * @__NL80211_COALESCE_RULE_INVALID: invalid number for nested attribute
+ * @NL80211_ATTR_COALESCE_RULE_DELAY: delay in msecs used for packet coalescing
+ * @NL80211_ATTR_COALESCE_RULE_CONDITION: condition for packet coalescence,
+ *	see &enum nl80211_coalesce_condition.
+ * @NL80211_ATTR_COALESCE_RULE_PKT_PATTERN: packet offset, pattern is matched
+ *	after these fixed number of bytes of received packet
+ * @NUM_NL80211_ATTR_COALESCE_RULE: number of attributes
+ * @NL80211_ATTR_COALESCE_RULE_MAX: max attribute number
+ */
+enum nl80211_attr_coalesce_rule {
+	__NL80211_COALESCE_RULE_INVALID,
+	NL80211_ATTR_COALESCE_RULE_DELAY,
+	NL80211_ATTR_COALESCE_RULE_CONDITION,
+	NL80211_ATTR_COALESCE_RULE_PKT_PATTERN,
+
+	/* keep last */
+	NUM_NL80211_ATTR_COALESCE_RULE,
+	NL80211_ATTR_COALESCE_RULE_MAX = NUM_NL80211_ATTR_COALESCE_RULE - 1
+};
+
+/**
+ * enum nl80211_coalesce_condition - coalesce rule conditions
+ * @NL80211_COALESCE_CONDITION_MATCH: coalaesce Rx packets when patterns
+ *	in a rule are matched.
+ * @NL80211_COALESCE_CONDITION_NO_MATCH: coalesce Rx packets when patterns
+ *	in a rule are not matched.
+ */
+enum nl80211_coalesce_condition {
+	NL80211_COALESCE_CONDITION_MATCH,
+	NL80211_COALESCE_CONDITION_NO_MATCH
+};
+
+/**
  * enum nl80211_iface_limit_attrs - limit attributes
  * @NL80211_IFACE_LIMIT_UNSPEC: (reserved)
  * @NL80211_IFACE_LIMIT_MAX: maximum number of interfaces that
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 672459b..853f754 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -462,6 +462,14 @@ int wiphy_register(struct wiphy *wiphy)
 		return -EINVAL;
 #endif
 
+	if (WARN_ON(wiphy->coalesce &&
+		    (!wiphy->coalesce->n_rules ||
+		     !wiphy->wowlan->n_patterns) &&
+		    (!wiphy->coalesce->pattern_min_len ||
+		     wiphy->coalesce->pattern_min_len >
+			wiphy->coalesce->pattern_max_len)))
+		return -EINVAL;
+
 	if (WARN_ON(wiphy->ap_sme_capa &&
 		    !(wiphy->flags & WIPHY_FLAG_HAVE_AP_SME)))
 		return -EINVAL;
@@ -668,6 +676,9 @@ void wiphy_unregister(struct wiphy *wiphy)
 		rdev_set_wakeup(rdev, false);
 #endif
 	cfg80211_rdev_free_wowlan(rdev);
+
+	cfg80211_rdev_free_coalesce(rdev->coalesce);
+	rdev->coalesce = NULL;
 }
 EXPORT_SYMBOL(wiphy_unregister);
 
diff --git a/net/wireless/core.h b/net/wireless/core.h
index a6b45bf..9ad43c6 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -79,6 +79,8 @@ struct cfg80211_registered_device {
 	/* netlink port which started critical protocol (0 means not started) */
 	u32 crit_proto_nlportid;
 
+	struct cfg80211_coalesce *coalesce;
+
 	/* must be last because of the way we do wiphy_priv(),
 	 * and it should at least be aligned to NETDEV_ALIGN */
 	struct wiphy wiphy __aligned(NETDEV_ALIGN);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 785761f..cc736ac 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -403,6 +403,14 @@ nl80211_wowlan_tcp_policy[NUM_NL80211_WOWLAN_TCP] = {
 	[NL80211_WOWLAN_TCP_WAKE_MASK] = { .len = 1 },
 };
 
+/* policy for coalesce rule attributes */
+static const struct nla_policy
+nl80211_coalesce_policy[NUM_NL80211_ATTR_COALESCE_RULE] = {
+	[NL80211_ATTR_COALESCE_RULE_DELAY] = { .type = NLA_U32 },
+	[NL80211_ATTR_COALESCE_RULE_CONDITION] = { .type = NLA_U32 },
+	[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN] = { .type = NLA_NESTED },
+};
+
 /* policy for GTK rekey offload attributes */
 static const struct nla_policy
 nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
@@ -995,6 +1003,26 @@ static int nl80211_send_wowlan(struct sk_buff *msg,
 }
 #endif
 
+static int nl80211_send_coalesce(struct sk_buff *msg,
+				 struct cfg80211_registered_device *dev)
+{
+	struct nl80211_coalesce_rule_support rule;
+
+	if (!dev->wiphy.coalesce)
+		return 0;
+
+	rule.max_rules = dev->wiphy.coalesce->n_rules;
+	rule.pat.max_patterns = dev->wiphy.coalesce->n_patterns;
+	rule.pat.min_pattern_len = dev->wiphy.coalesce->pattern_min_len;
+	rule.pat.max_pattern_len = dev->wiphy.coalesce->pattern_max_len;
+	rule.pat.max_pkt_offset = dev->wiphy.coalesce->max_pkt_offset;
+
+	if (nla_put(msg, NL80211_ATTR_COALESCE_RULE, sizeof(rule), &rule))
+		return -ENOBUFS;
+
+	return 0;
+}
+
 static int nl80211_send_band_rateinfo(struct sk_buff *msg,
 				      struct ieee80211_supported_band *sband)
 {
@@ -1513,6 +1541,12 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
 			    dev->wiphy.vht_capa_mod_mask))
 			goto nla_put_failure;
 
+		state->split_start++;
+		break;
+	case 10:
+		if (nl80211_send_coalesce(msg, dev))
+			goto nla_put_failure;
+
 		/* done */
 		state->split_start = 0;
 		break;
@@ -8030,6 +8064,250 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
 }
 #endif
 
+static int nl80211_send_coalesce_rules(struct sk_buff *msg,
+				       struct cfg80211_registered_device *rdev)
+{
+	struct nlattr *nl_pats, *nl_pat, *nl_rule, *nl_rules;
+	int i, j, pat_len;
+	struct cfg80211_coalesce_rules *rule;
+
+	if (!rdev->coalesce->n_rules)
+		return 0;
+
+	nl_rules = nla_nest_start(msg, NL80211_ATTR_COALESCE_RULE);
+	if (!nl_rules)
+		return -ENOBUFS;
+
+	for (i = 0; i < rdev->coalesce->n_rules; i++) {
+		nl_rule = nla_nest_start(msg, i + 1);
+		if (!nl_rule)
+			return -ENOBUFS;
+
+		rule = rdev->coalesce->rules[i];
+		if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_DELAY,
+				rule->delay))
+			return -ENOBUFS;
+
+		if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_CONDITION,
+				rule->condition))
+			return -ENOBUFS;
+
+		nl_pats = nla_nest_start(msg,
+				NL80211_ATTR_COALESCE_RULE_PKT_PATTERN);
+		if (!nl_pats)
+			return -ENOBUFS;
+
+		for (j = 0; j < rule->n_patterns; j++) {
+			nl_pat = nla_nest_start(msg, j + 1);
+			if (!nl_pat)
+				return -ENOBUFS;
+			pat_len = rule->patterns[j].pattern_len;
+			if (nla_put(msg, NL80211_PKTPAT_MASK,
+				    DIV_ROUND_UP(pat_len, 8),
+				    rule->patterns[j].mask) ||
+			    nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
+				    rule->patterns[j].pattern) ||
+			    nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
+					rule->patterns[j].pkt_offset))
+				return -ENOBUFS;
+			nla_nest_end(msg, nl_pat);
+		}
+		nla_nest_end(msg, nl_pats);
+		nla_nest_end(msg, nl_rule);
+	}
+	nla_nest_end(msg, nl_rules);
+
+	return 0;
+}
+
+static int nl80211_get_coalesce(struct sk_buff *skb, struct genl_info *info)
+{
+	struct cfg80211_registered_device *rdev = info->user_ptr[0];
+	struct sk_buff *msg;
+	void *hdr;
+
+	if (!rdev->wiphy.coalesce)
+		return -EOPNOTSUPP;
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!msg)
+		return -ENOMEM;
+
+	hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
+			     NL80211_CMD_GET_COALESCE);
+	if (!hdr)
+		goto nla_put_failure;
+
+	if (rdev->coalesce && nl80211_send_coalesce_rules(msg, rdev))
+		goto nla_put_failure;
+
+	genlmsg_end(msg, hdr);
+	return genlmsg_reply(msg, info);
+
+nla_put_failure:
+	nlmsg_free(msg);
+	return -ENOBUFS;
+}
+
+void cfg80211_rdev_free_coalesce(struct cfg80211_coalesce *coalesce)
+{
+	int i, j;
+	struct cfg80211_coalesce_rules *rule;
+
+	if (!coalesce)
+		return;
+
+	for (i = 0; i < coalesce->n_rules; i++) {
+		rule = coalesce->rules[i];
+		for (j = 0; j < rule->n_patterns; j++)
+			kfree(rule->patterns[j].mask);
+		kfree(rule->patterns);
+		kfree(rule);
+	}
+	kfree(coalesce->rules);
+	kfree(coalesce);
+}
+
+static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev,
+				       struct nlattr *rule,
+				       struct cfg80211_coalesce_rules *new_rule)
+{
+	int err, i;
+	const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
+	struct nlattr *tb[NUM_NL80211_ATTR_COALESCE_RULE], *pat;
+	int rem, pat_len, mask_len, pkt_offset, n_patterns = 0;
+	struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
+
+	err = nla_parse(tb, NL80211_ATTR_COALESCE_RULE_MAX, nla_data(rule),
+			nla_len(rule), nl80211_coalesce_policy);
+	if (err)
+		return err;
+
+	memset(new_rule, 0, sizeof(*new_rule));
+	new_rule->delay = nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_DELAY]);
+	new_rule->condition =
+		nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_CONDITION]);
+	if (new_rule->condition != NL80211_COALESCE_CONDITION_MATCH &&
+	    new_rule->condition != NL80211_COALESCE_CONDITION_NO_MATCH)
+		return -EINVAL;
+
+	if (!tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN])
+		return -EINVAL;
+
+	nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
+			    rem)
+		n_patterns++;
+	if (n_patterns > coalesce->n_patterns)
+		return -EINVAL;
+
+	new_rule->patterns = kcalloc(n_patterns, sizeof(new_rule->patterns[0]),
+				     GFP_KERNEL);
+	if (!new_rule->patterns)
+		return -ENOMEM;
+
+	new_rule->n_patterns = n_patterns;
+	i = 0;
+
+	nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
+			    rem) {
+		err = -EINVAL;
+		nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat),
+			  nla_len(pat), NULL);
+		if (!pat_tb[NL80211_PKTPAT_MASK] ||
+		    !pat_tb[NL80211_PKTPAT_PATTERN])
+			goto error;
+		pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
+		mask_len = DIV_ROUND_UP(pat_len, 8);
+		if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
+			goto error;
+		if (pat_len > coalesce->pattern_max_len ||
+		    pat_len < coalesce->pattern_min_len)
+			goto error;
+
+		if (!pat_tb[NL80211_PKTPAT_OFFSET])
+			pkt_offset = 0;
+		else
+			pkt_offset = nla_get_u32(pat_tb[NL80211_PKTPAT_OFFSET]);
+		if (pkt_offset > coalesce->max_pkt_offset)
+			goto error;
+		new_rule->patterns[i].pkt_offset = pkt_offset;
+
+		new_rule->patterns[i].mask =
+			kmalloc(mask_len + pat_len, GFP_KERNEL);
+		err = -ENOMEM;
+		if (!new_rule->patterns[i].mask)
+			goto error;
+		new_rule->patterns[i].pattern =
+			new_rule->patterns[i].mask + mask_len;
+		memcpy(new_rule->patterns[i].mask,
+		       nla_data(pat_tb[NL80211_PKTPAT_MASK]), mask_len);
+		new_rule->patterns[i].pattern_len = pat_len;
+		memcpy(new_rule->patterns[i].pattern,
+		       nla_data(pat_tb[NL80211_PKTPAT_PATTERN]), pat_len);
+		i++;
+	}
+
+	return 0;
+error:
+	for (i = 0; i < new_rule->n_patterns; i++)
+		kfree(new_rule->patterns[i].mask);
+	kfree(new_rule->patterns);
+	return err;
+}
+
+static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info)
+{
+	struct cfg80211_registered_device *rdev = info->user_ptr[0];
+	const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
+	struct cfg80211_coalesce_rules new_rule = {};
+	struct cfg80211_coalesce_rules *nrule;
+	struct cfg80211_coalesce *new_coalesce;
+	int err, rem_rule;
+	struct nlattr *rule;
+
+	if (!rdev->wiphy.coalesce)
+		return -EOPNOTSUPP;
+	if (!rdev->ops->set_coalesce)
+		return -EOPNOTSUPP;
+
+	if (!info->attrs[NL80211_ATTR_COALESCE_RULE]) {
+		cfg80211_rdev_free_coalesce(rdev->coalesce);
+		rdev->coalesce = NULL;
+		rdev->ops->set_coalesce(&rdev->wiphy, NULL);
+		return 0;
+	}
+
+	new_coalesce = kzalloc(sizeof(*new_coalesce), GFP_KERNEL);
+	new_coalesce->rules = kcalloc(coalesce->n_rules,
+					sizeof(void *), GFP_KERNEL);
+	nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
+			    rem_rule) {
+		memset(&new_rule, 0, sizeof(new_rule));
+		err = nl80211_parse_coalesce_rule(rdev, rule, &new_rule);
+		if (err)
+			goto error;
+
+		nrule = kmemdup(&new_rule, sizeof(new_rule), GFP_KERNEL);
+		if (!nrule) {
+			err = -ENOMEM;
+			goto error;
+		}
+		new_coalesce->rules[new_coalesce->n_rules++] = nrule;
+	}
+
+	cfg80211_rdev_free_coalesce(rdev->coalesce);
+	rdev->coalesce = new_coalesce;
+
+	err = rdev->ops->set_coalesce(&rdev->wiphy, rdev->coalesce);
+	if (err)
+		goto error;
+
+	return 0;
+error:
+	cfg80211_rdev_free_coalesce(new_coalesce);
+	return err;
+}
+
 static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info)
 {
 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -9037,6 +9315,21 @@ static struct genl_ops nl80211_ops[] = {
 		.flags = GENL_ADMIN_PERM,
 		.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
 				  NL80211_FLAG_NEED_RTNL,
+	},
+	{
+		.cmd = NL80211_CMD_GET_COALESCE,
+		.doit = nl80211_get_coalesce,
+		.policy = nl80211_policy,
+		.internal_flags = NL80211_FLAG_NEED_WIPHY |
+				  NL80211_FLAG_NEED_RTNL,
+	},
+	{
+		.cmd = NL80211_CMD_SET_COALESCE,
+		.doit = nl80211_set_coalesce,
+		.policy = nl80211_policy,
+		.flags = GENL_ADMIN_PERM,
+		.internal_flags = NL80211_FLAG_NEED_WIPHY |
+				  NL80211_FLAG_NEED_RTNL,
 	}
 };
 
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index a4073e8..d5ef819 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -74,4 +74,6 @@ nl80211_radar_notify(struct cfg80211_registered_device *rdev,
 		     enum nl80211_radar_event event,
 		     struct net_device *netdev, gfp_t gfp);
 
+void cfg80211_rdev_free_coalesce(struct cfg80211_coalesce *coalesce);
+
 #endif /* __NET_WIRELESS_NL80211_H */
-- 
1.8.0


^ permalink raw reply related

* Re: pull request: wireless 2013-06-25
From: David Miller @ 2013-06-25 23:05 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, netdev, linux-kernel
In-Reply-To: <20130625174507.GB31220@tuxdriver.com>

From: "John W. Linville" <linville@tuxdriver.com>
Date: Tue, 25 Jun 2013 13:45:07 -0400

> A few more late-breaking fixes hoping for 3.10...
> 
> Regarding the Bluetooth fix, Gustavo says:
> 
> "A important fix to 3.10, this patch fixes an issues that was preventing
> the l2cap info response command to be handled properly."
> 
> Also for that Bluetooth fix, Johan adds:
> 
> "Once the code gives up parsing this PDU it also gives up essential
> parts of the L2CAP connection creation process, i.e. without this
> patch the stack will fail to establish connections properly."
> 
> Moving onto ath9k, Felix Fietkau fixes an RCU locking issue in
> the transmit path.  As for ath9k_htc, Sujith Manoharan fixes some
> authentication timeouts by ensuring that a chip reset is done when
> IDLE is turned off.
> 
> I think these are all micro-fixes that shouldn't cause any trouble.
> Please let me know if there are problems!

Pulled, thanks John.

^ permalink raw reply

* Re: [PATCH] rt2x00: rt2800lib: fix default TX power check for RT55xx
From: Gertjan van Wingerde @ 2013-06-25 21:08 UTC (permalink / raw)
  To: Gabor Juhos
  Cc: John Linville, linux-wireless@vger.kernel.org,
	users@rt2x00.serialmonkey.com, Gabor Juhos,
	stable@vger.kernel.org, #@arrakis.dune.hu, 3.10@arrakis.dune.hu
In-Reply-To: <1372193849-21630-1-git-send-email-juhosg@openwrt.org>



Sent from my iPad

On 25 jun. 2013, at 22:57, Gabor Juhos <juhosg@openwrt.org> wrote:

> The code writes the default_power2 value into the TX field
> of the RFCSR50 register, however the condition in the if
> statement uses default_power1. Due to this, wrong TX power
> value might be written into the register.
> 
> Use the correct value in the condition to fix the issue.
> 
> Compile tested only.
> 
> Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
> Cc: stable@vger.kernel.org # 3.10

Good catch. Thanks for spotting it.

Acked-by: Gertjan van Wingerde <gwingerde@gmail.com>


> ---
> John,
> 
> This is for 3.11. Even though the original code is introduced in
> 3.10-rc2 phase, but it is already too late to fix it in 3.10.
> 
> -Gabor
> ---
> drivers/net/wireless/rt2x00/rt2800lib.c |    2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
> index 25f7dbe..1f80ea5 100644
> --- a/drivers/net/wireless/rt2x00/rt2800lib.c
> +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
> @@ -2392,7 +2392,7 @@ static void rt2800_config_channel_rf55xx(struct rt2x00_dev *rt2x00dev,
>    rt2800_rfcsr_write(rt2x00dev, 49, rfcsr);
> 
>    rt2800_rfcsr_read(rt2x00dev, 50, &rfcsr);
> -    if (info->default_power1 > power_bound)
> +    if (info->default_power2 > power_bound)
>        rt2x00_set_field8(&rfcsr, RFCSR50_TX, power_bound);
>    else
>        rt2x00_set_field8(&rfcsr, RFCSR50_TX, info->default_power2);
> -- 
> 1.7.10
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: pull request: bluetooth 2013-06-23
From: Gustavo Padovan @ 2013-06-25 21:00 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: Pavel Machek, linville, linux-wireless, linux-bluetooth,
	linux-kernel, Rafael J. Wysocki
In-Reply-To: <E95EC814-F064-4AEB-AE13-79982D3BE5E8@holtmann.org>

Hi Marcel,

* Marcel Holtmann <marcel@holtmann.org> [2013-06-25 13:49:19 -0700]:

> Hi Pavel,
> 
> >> Jaganath Kanakkassery (1):
> >>      Bluetooth: Fix invalid length check in l2cap_information_rsp()
> > 
> > Could we add the "3.10 vs. thinkpad x60" patch that fixes regression?
> > It is from Johan Hedberg…
> 
> that one went into net-next tree. It is scheduled for 3.11 right now.
> 
> After 3.10 is out, maybe it can go into -stable, but otherwise I think it is bit late now. Unless someone wants to cherry-pick it.

That patch is actually in 3.10 already, it was included in the last pull
request and John took it to wireless.git.

	Gustavo

^ permalink raw reply

* [PATCH] rt2x00: rt2800lib: fix default TX power check for RT55xx
From: Gabor Juhos @ 2013-06-25 20:57 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless, users, Gabor Juhos, stable, #, 3.10

The code writes the default_power2 value into the TX field
of the RFCSR50 register, however the condition in the if
statement uses default_power1. Due to this, wrong TX power
value might be written into the register.

Use the correct value in the condition to fix the issue.

Compile tested only.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Cc: stable@vger.kernel.org # 3.10
---
John,

This is for 3.11. Even though the original code is introduced in
3.10-rc2 phase, but it is already too late to fix it in 3.10.

-Gabor
---
 drivers/net/wireless/rt2x00/rt2800lib.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 25f7dbe..1f80ea5 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2392,7 +2392,7 @@ static void rt2800_config_channel_rf55xx(struct rt2x00_dev *rt2x00dev,
 	rt2800_rfcsr_write(rt2x00dev, 49, rfcsr);
 
 	rt2800_rfcsr_read(rt2x00dev, 50, &rfcsr);
-	if (info->default_power1 > power_bound)
+	if (info->default_power2 > power_bound)
 		rt2x00_set_field8(&rfcsr, RFCSR50_TX, power_bound);
 	else
 		rt2x00_set_field8(&rfcsr, RFCSR50_TX, info->default_power2);
-- 
1.7.10


^ permalink raw reply related

* Re: pull request: bluetooth 2013-06-23
From: Marcel Holtmann @ 2013-06-25 20:49 UTC (permalink / raw)
  To: Pavel Machek
  Cc: Gustavo Padovan, linville, linux-wireless, linux-bluetooth,
	linux-kernel, Rafael J. Wysocki
In-Reply-To: <20130625201217.GA13879@amd.pavel.ucw.cz>

Hi Pavel,

>> Jaganath Kanakkassery (1):
>>      Bluetooth: Fix invalid length check in l2cap_information_rsp()
> 
> Could we add the "3.10 vs. thinkpad x60" patch that fixes regression?
> It is from Johan Hedberg…

that one went into net-next tree. It is scheduled for 3.11 right now.

After 3.10 is out, maybe it can go into -stable, but otherwise I think it is bit late now. Unless someone wants to cherry-pick it.

Regards

Marcel


^ permalink raw reply

* [PATCH 5/5] wlcore: add device tree support to the sdio module
From: Luciano Coelho @ 2013-06-25 20:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: coelho, tony
In-Reply-To: <1372192406-29430-1-git-send-email-coelho@ti.com>

If platform data is not available, try to get the required information
from the device tree.  Register an OF match table and parse the
appropriate device tree nodes.

Signed-off-by: Luciano Coelho <coelho@ti.com>
---
 drivers/net/wireless/ti/wlcore/sdio.c |   75 ++++++++++++++++++++++++++++++---
 1 file changed, 69 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c
index 4c7e8ac..1ddda84 100644
--- a/drivers/net/wireless/ti/wlcore/sdio.c
+++ b/drivers/net/wireless/ti/wlcore/sdio.c
@@ -30,7 +30,7 @@
 #include <linux/mmc/sdio_ids.h>
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
-#include <linux/gpio.h>
+#include <linux/of_irq.h>
 #include <linux/wl12xx.h>
 #include <linux/pm_runtime.h>
 #include <linux/printk.h>
@@ -214,6 +214,49 @@ static struct wl1271_if_operations sdio_ops = {
 	.set_block_size = wl1271_sdio_set_block_size,
 };
 
+static struct wl12xx_platform_data *wlcore_get_pdata_from_of(struct device *dev)
+{
+	struct wl12xx_platform_data *pdata;
+	struct device_node *np = dev->of_node;
+
+	if (!np) {
+		np = of_find_matching_node(NULL, dev->driver->of_match_table);
+		if (!np) {
+			dev_notice(dev, "device tree node not available\n");
+			pdata = ERR_PTR(-ENODEV);
+			goto out;
+		}
+	}
+
+	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		dev_err(dev, "can't allocate platform data\n");
+		pdata = ERR_PTR(-ENODEV);
+		goto out;
+	}
+
+	pdata->irq = irq_of_parse_and_map(np, 0);
+	if (pdata->irq < 0) {
+		dev_err(dev, "can't get interrupt gpio from the device tree\n");
+		goto out_free;
+	}
+
+	/* TODO: make sure we have this when needed (ie. for WL6 and WL7) */
+	of_property_read_u32(np, "refclock", &pdata->board_ref_clock);
+
+	/* TODO: make sure we have this when needed (ie. for WL7) */
+	of_property_read_u32(np, "tcxoclock", &pdata->board_tcxo_clock);
+
+	goto out;
+
+out_free:
+	kfree(pdata);
+	pdata = ERR_PTR(-ENODEV);
+
+out:
+	return pdata;
+}
+
 static int wl1271_probe(struct sdio_func *func,
 				  const struct sdio_device_id *id)
 {
@@ -248,11 +291,22 @@ static int wl1271_probe(struct sdio_func *func,
 	/* Use block mode for transferring over one block size of data */
 	func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
 
+	/* The pdata allocated here is freed when the device is freed,
+	 * so we don't need an additional out label to free it in case
+	 * of error further on.
+	 */
+
+	/* Try to get legacy platform data from the board file */
 	pdev_data->pdata = wl12xx_get_platform_data();
 	if (IS_ERR(pdev_data->pdata)) {
-		ret = PTR_ERR(pdev_data->pdata);
-		dev_err(glue->dev, "missing wlan platform data: %d\n", ret);
-		goto out_free_glue;
+		dev_info(&func->dev,
+			 "legacy platform data not found, trying device tree\n");
+
+		pdev_data->pdata = wlcore_get_pdata_from_of(&func->dev);
+		if (IS_ERR(pdev_data->pdata)) {
+			dev_err(&func->dev, "can't get platform data\n");
+			goto out_free_glue;
+		}
 	}
 
 	/* if sdio can keep power while host is suspended, enable wow */
@@ -386,16 +440,25 @@ static const struct dev_pm_ops wl1271_sdio_pm_ops = {
 };
 #endif
 
+static const struct of_device_id wlcore_sdio_of_match_table[] = {
+	{ .compatible = "ti,wilink6" },
+	{ .compatible = "ti,wilink7" },
+	{ .compatible = "ti,wilink8" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, wlcore_sdio_of_match_table);
+
 static struct sdio_driver wl1271_sdio_driver = {
 	.name		= "wl1271_sdio",
 	.id_table	= wl1271_devices,
 	.probe		= wl1271_probe,
 	.remove		= wl1271_remove,
-#ifdef CONFIG_PM
 	.drv = {
+#ifdef CONFIG_PM
 		.pm = &wl1271_sdio_pm_ops,
-	},
 #endif
+		.of_match_table = of_match_ptr(wlcore_sdio_of_match_table),
+	},
 };
 
 static int __init wl1271_init(void)
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 4/5] wlcore: always use one-shot IRQ
From: Luciano Coelho @ 2013-06-25 20:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: coelho, tony
In-Reply-To: <1372192406-29430-1-git-send-email-coelho@ti.com>

Since we are now using threaded IRQs without the primary handler, we
need to set IRQF_ONESHOT, otherwise our request will fail.

Signed-off-by: Luciano Coelho <coelho@ti.com>
---
 drivers/net/wireless/ti/wlcore/main.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index d306cd5..bc1cff3 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -5927,7 +5927,8 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
 
 	wl->irq = platform_get_irq(pdev, 0);
 	wl->if_ops = pdev_data->if_ops;
-	wl->irq_flags = pdata->irq_flags;
+	/* Since we don't use the primary handler, we must set ONESHOT */
+	wl->irq_flags = pdata->irq_flags | IRQF_ONESHOT;
 
 	ret = request_threaded_irq(wl->irq, NULL, wlcore_irq,
 				   wl->irq_flags, pdev->name, wl);
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 3/5] wlcore: remove pwr_in_suspend from platform data
From: Luciano Coelho @ 2013-06-25 20:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: coelho, tony
In-Reply-To: <1372192406-29430-1-git-send-email-coelho@ti.com>

The pwr_in_suspend flag depends on the MMC settings which can be
retrieved from the SDIO subsystem, so it doesn't need to be part of
the platform data structure.  Move it to the platform device data that
is passed from SDIO to wlcore.

Signed-off-by: Luciano Coelho <coelho@ti.com>
---
 drivers/net/wireless/ti/wlcore/main.c     |    2 +-
 drivers/net/wireless/ti/wlcore/sdio.c     |    2 +-
 drivers/net/wireless/ti/wlcore/wlcore_i.h |    1 +
 include/linux/wl12xx.h                    |    1 -
 4 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index e7294b8..d306cd5 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -5941,7 +5941,7 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
 	if (!ret) {
 		wl->irq_wake_enabled = true;
 		device_init_wakeup(wl->dev, 1);
-		if (pdata->pwr_in_suspend)
+		if (pdev_data->pwr_in_suspend)
 			wl->hw->wiphy->wowlan = &wlcore_wowlan_support;
 	}
 #endif
diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c
index 29ef249..4c7e8ac 100644
--- a/drivers/net/wireless/ti/wlcore/sdio.c
+++ b/drivers/net/wireless/ti/wlcore/sdio.c
@@ -260,7 +260,7 @@ static int wl1271_probe(struct sdio_func *func,
 	dev_dbg(glue->dev, "sdio PM caps = 0x%x\n", mmcflags);
 
 	if (mmcflags & MMC_PM_KEEP_POWER)
-		pdev_data->pdata->pwr_in_suspend = true;
+		pdev_data->pwr_in_suspend = true;
 
 	sdio_set_drvdata(func, glue);
 
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h
index e5e1464..f2c4227 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
@@ -209,6 +209,7 @@ struct wl1271_if_operations {
 struct wlcore_platdev_data {
 	struct wl12xx_platform_data *pdata;
 	struct wl1271_if_operations *if_ops;
+	bool pwr_in_suspend;
 };
 
 #define MAX_NUM_KEYS 14
diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h
index 04e3096..1e4ed6e 100644
--- a/include/linux/wl12xx.h
+++ b/include/linux/wl12xx.h
@@ -60,7 +60,6 @@ struct wl12xx_platform_data {
 	unsigned long irq_flags;
 	int board_ref_clock;
 	int board_tcxo_clock;
-	bool pwr_in_suspend;
 };
 
 #ifdef CONFIG_WILINK_PLATFORM_DATA
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 1/5] wl1251: split wl251 platform data to a separate structure
From: Luciano Coelho @ 2013-06-25 20:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: coelho, tony
In-Reply-To: <1372192406-29430-1-git-send-email-coelho@ti.com>

Move the wl1251 part of the wl12xx platform data structure into a new
structure specifically for wl1251.  Change the platform data built-in
block and board files accordingly.

Cc: Tony Lindgren <tony@atomide.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
---
 arch/arm/mach-omap2/board-omap3pandora.c       |    4 +--
 arch/arm/mach-omap2/board-rx51-peripherals.c   |    2 +-
 drivers/net/wireless/ti/wilink_platform_data.c |   37 ++++++++++++++++++++----
 drivers/net/wireless/ti/wl1251/sdio.c          |   12 ++++----
 drivers/net/wireless/ti/wl1251/spi.c           |    2 +-
 include/linux/wl12xx.h                         |   22 +++++++++++++-
 6 files changed, 62 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 28133d5..bf06d95 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -540,7 +540,7 @@ static struct spi_board_info omap3pandora_spi_board_info[] __initdata = {
 
 static void __init pandora_wl1251_init(void)
 {
-	struct wl12xx_platform_data pandora_wl1251_pdata;
+	struct wl1251_platform_data pandora_wl1251_pdata;
 	int ret;
 
 	memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata));
@@ -554,7 +554,7 @@ static void __init pandora_wl1251_init(void)
 		goto fail_irq;
 
 	pandora_wl1251_pdata.use_eeprom = true;
-	ret = wl12xx_set_platform_data(&pandora_wl1251_pdata);
+	ret = wl1251_set_platform_data(&pandora_wl1251_pdata);
 	if (ret < 0)
 		goto fail_irq;
 
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index 18ca61e..733f3f2 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -80,7 +80,7 @@ enum {
 	RX51_SPI_MIPID,		/* LCD panel */
 };
 
-static struct wl12xx_platform_data wl1251_pdata;
+static struct wl1251_platform_data wl1251_pdata;
 static struct tsc2005_platform_data tsc2005_pdata;
 
 #if defined(CONFIG_SENSORS_LIS3_I2C) || defined(CONFIG_SENSORS_LIS3_I2C_MODULE)
diff --git a/drivers/net/wireless/ti/wilink_platform_data.c b/drivers/net/wireless/ti/wilink_platform_data.c
index 998e958..a92bd3e 100644
--- a/drivers/net/wireless/ti/wilink_platform_data.c
+++ b/drivers/net/wireless/ti/wilink_platform_data.c
@@ -23,17 +23,17 @@
 #include <linux/err.h>
 #include <linux/wl12xx.h>
 
-static struct wl12xx_platform_data *platform_data;
+static struct wl12xx_platform_data *wl12xx_platform_data;
 
 int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
 {
-	if (platform_data)
+	if (wl12xx_platform_data)
 		return -EBUSY;
 	if (!data)
 		return -EINVAL;
 
-	platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
-	if (!platform_data)
+	wl12xx_platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
+	if (!wl12xx_platform_data)
 		return -ENOMEM;
 
 	return 0;
@@ -41,9 +41,34 @@ int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
 
 struct wl12xx_platform_data *wl12xx_get_platform_data(void)
 {
-	if (!platform_data)
+	if (!wl12xx_platform_data)
 		return ERR_PTR(-ENODEV);
 
-	return platform_data;
+	return wl12xx_platform_data;
 }
 EXPORT_SYMBOL(wl12xx_get_platform_data);
+
+static struct wl1251_platform_data *wl1251_platform_data;
+
+int __init wl1251_set_platform_data(const struct wl1251_platform_data *data)
+{
+	if (wl1251_platform_data)
+		return -EBUSY;
+	if (!data)
+		return -EINVAL;
+
+	wl1251_platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
+	if (!wl1251_platform_data)
+		return -ENOMEM;
+
+	return 0;
+}
+
+struct wl1251_platform_data *wl1251_get_platform_data(void)
+{
+	if (!wl1251_platform_data)
+		return ERR_PTR(-ENODEV);
+
+	return wl1251_platform_data;
+}
+EXPORT_SYMBOL(wl1251_get_platform_data);
diff --git a/drivers/net/wireless/ti/wl1251/sdio.c b/drivers/net/wireless/ti/wl1251/sdio.c
index e2b3d9c..b75a37a 100644
--- a/drivers/net/wireless/ti/wl1251/sdio.c
+++ b/drivers/net/wireless/ti/wl1251/sdio.c
@@ -227,7 +227,7 @@ static int wl1251_sdio_probe(struct sdio_func *func,
 	struct wl1251 *wl;
 	struct ieee80211_hw *hw;
 	struct wl1251_sdio *wl_sdio;
-	const struct wl12xx_platform_data *wl12xx_board_data;
+	const struct wl1251_platform_data *wl1251_board_data;
 
 	hw = wl1251_alloc_hw();
 	if (IS_ERR(hw))
@@ -254,11 +254,11 @@ static int wl1251_sdio_probe(struct sdio_func *func,
 	wl->if_priv = wl_sdio;
 	wl->if_ops = &wl1251_sdio_ops;
 
-	wl12xx_board_data = wl12xx_get_platform_data();
-	if (!IS_ERR(wl12xx_board_data)) {
-		wl->set_power = wl12xx_board_data->set_power;
-		wl->irq = wl12xx_board_data->irq;
-		wl->use_eeprom = wl12xx_board_data->use_eeprom;
+	wl1251_board_data = wl1251_get_platform_data();
+	if (!IS_ERR(wl1251_board_data)) {
+		wl->set_power = wl1251_board_data->set_power;
+		wl->irq = wl1251_board_data->irq;
+		wl->use_eeprom = wl1251_board_data->use_eeprom;
 	}
 
 	if (wl->irq) {
diff --git a/drivers/net/wireless/ti/wl1251/spi.c b/drivers/net/wireless/ti/wl1251/spi.c
index c7dc6fe..6bbbfe6 100644
--- a/drivers/net/wireless/ti/wl1251/spi.c
+++ b/drivers/net/wireless/ti/wl1251/spi.c
@@ -238,7 +238,7 @@ static const struct wl1251_if_operations wl1251_spi_ops = {
 
 static int wl1251_spi_probe(struct spi_device *spi)
 {
-	struct wl12xx_platform_data *pdata;
+	struct wl1251_platform_data *pdata;
 	struct ieee80211_hw *hw;
 	struct wl1251 *wl;
 	int ret;
diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h
index a54fe82..b516b4f 100644
--- a/include/linux/wl12xx.h
+++ b/include/linux/wl12xx.h
@@ -48,11 +48,15 @@ enum {
 	WL12XX_TCXOCLOCK_33_6	= 7, /* 33.6 MHz */
 };
 
-struct wl12xx_platform_data {
+struct wl1251_platform_data {
 	void (*set_power)(bool enable);
 	/* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */
 	int irq;
 	bool use_eeprom;
+};
+
+struct wl12xx_platform_data {
+	int irq;
 	int board_ref_clock;
 	int board_tcxo_clock;
 	unsigned long platform_quirks;
@@ -68,6 +72,10 @@ int wl12xx_set_platform_data(const struct wl12xx_platform_data *data);
 
 struct wl12xx_platform_data *wl12xx_get_platform_data(void);
 
+int wl1251_set_platform_data(const struct wl1251_platform_data *data);
+
+struct wl1251_platform_data *wl1251_get_platform_data(void);
+
 #else
 
 static inline
@@ -82,6 +90,18 @@ struct wl12xx_platform_data *wl12xx_get_platform_data(void)
 	return ERR_PTR(-ENODATA);
 }
 
+static inline
+int wl1251_set_platform_data(const struct wl1251_platform_data *data)
+{
+	return -ENOSYS;
+}
+
+static inline
+struct wl1251_platform_data *wl1251_get_platform_data(void)
+{
+	return ERR_PTR(-ENODATA);
+}
+
 #endif
 
 #endif
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 2/5] wlcore: use irq_flags in pdata instead of hiding it behing a quirk
From: Luciano Coelho @ 2013-06-25 20:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: coelho, tony
In-Reply-To: <1372192406-29430-1-git-send-email-coelho@ti.com>

The platform_quirk element in the platform data was used to change the
way the IRQ is triggered.  When set, the EDGE_IRQ quirk would change
the irqflags used and treat edge trigger differently from the rest.

Instead of hiding this irq flag setting behind the quirk, export the
whole irq_flags element and let the board file define what to use.
This will be more meaningful than driver-specific quirks when we
switch to DT.

Cc: Tony Lindgren <tony@atomide.com>
Cc: Sekhar Nori <nsekhar@ti.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
---
 arch/arm/mach-davinci/board-da850-evm.c      |    2 +-
 arch/arm/mach-omap2/board-4430sdp.c          |    1 +
 arch/arm/mach-omap2/board-omap3evm.c         |    1 +
 arch/arm/mach-omap2/board-omap4panda.c       |    1 +
 arch/arm/mach-omap2/board-zoom-peripherals.c |    1 +
 drivers/net/wireless/ti/wlcore/debugfs.c     |    2 +-
 drivers/net/wireless/ti/wlcore/main.c        |   13 +++----------
 drivers/net/wireless/ti/wlcore/wlcore.h      |    5 ++---
 include/linux/wl12xx.h                       |    5 +----
 9 files changed, 12 insertions(+), 19 deletions(-)

diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index 8a24b6c..d2a2a98 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -1377,8 +1377,8 @@ static const short da850_wl12xx_pins[] __initconst = {
 
 static struct wl12xx_platform_data da850_wl12xx_wlan_data __initdata = {
 	.irq			= -1,
+	.irq_flags		= IRQF_TRIGGER_RISING,
 	.board_ref_clock	= WL12XX_REFCLOCK_38,
-	.platform_quirks	= WL12XX_PLATFORM_QUIRK_EDGE_IRQ,
 };
 
 static __init int da850_wl12xx_init(void)
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 56a9a4f..c2334aa 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -693,6 +693,7 @@ static void __init omap4_sdp4430_wifi_mux_init(void)
 }
 
 static struct wl12xx_platform_data omap4_sdp4430_wlan_data __initdata = {
+	.irq_flags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
 	.board_ref_clock = WL12XX_REFCLOCK_26,
 	.board_tcxo_clock = WL12XX_TCXOCLOCK_26,
 };
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index f76d0de..a0c0adf 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -458,6 +458,7 @@ static struct platform_device omap3evm_wlan_regulator = {
 };
 
 struct wl12xx_platform_data omap3evm_wlan_data __initdata = {
+	.irq_flags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
 	.board_ref_clock = WL12XX_REFCLOCK_38, /* 38.4 MHz */
 };
 #endif
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 1e2c75e..ba00862 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -230,6 +230,7 @@ static struct platform_device omap_vwlan_device = {
 };
 
 static struct wl12xx_platform_data omap_panda_wlan_data  __initdata = {
+	.irq_flags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
 	.board_ref_clock = WL12XX_REFCLOCK_38, /* 38.4 MHz */
 };
 
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
index a90375d..ced012c 100644
--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -244,6 +244,7 @@ static struct platform_device *zoom_devices[] __initdata = {
 };
 
 static struct wl12xx_platform_data omap_zoom_wlan_data __initdata = {
+	.irq_flags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
 	.board_ref_clock = WL12XX_REFCLOCK_26, /* 26 MHz */
 };
 
diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c
index c3e1f79..5eff663 100644
--- a/drivers/net/wireless/ti/wlcore/debugfs.c
+++ b/drivers/net/wireless/ti/wlcore/debugfs.c
@@ -486,7 +486,7 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf,
 	DRIVER_STATE_PRINT_HEX(irq);
 	/* TODO: ref_clock and tcxo_clock were moved to wl12xx priv */
 	DRIVER_STATE_PRINT_HEX(hw_pg_ver);
-	DRIVER_STATE_PRINT_HEX(platform_quirks);
+	DRIVER_STATE_PRINT_HEX(irq_flags);
 	DRIVER_STATE_PRINT_HEX(chip.id);
 	DRIVER_STATE_PRINT_STR(chip.fw_ver_str);
 	DRIVER_STATE_PRINT_STR(chip.phy_fw_ver_str);
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index b8db55c..e7294b8 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -516,7 +516,7 @@ static int wlcore_irq_locked(struct wl1271 *wl)
 	 * In case edge triggered interrupt must be used, we cannot iterate
 	 * more than once without introducing race conditions with the hardirq.
 	 */
-	if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
+	if (wl->irq_flags & IRQF_TRIGGER_RISING)
 		loopcount = 1;
 
 	wl1271_debug(DEBUG_IRQ, "IRQ work");
@@ -5765,7 +5765,6 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size,
 	wl->ap_ps_map = 0;
 	wl->ap_fw_ps_map = 0;
 	wl->quirks = 0;
-	wl->platform_quirks = 0;
 	wl->system_hlid = WL12XX_SYSTEM_HLID;
 	wl->active_sta_count = 0;
 	wl->active_link_count = 0;
@@ -5901,7 +5900,6 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
 	struct platform_device *pdev = wl->pdev;
 	struct wlcore_platdev_data *pdev_data = pdev->dev.platform_data;
 	struct wl12xx_platform_data *pdata = pdev_data->pdata;
-	unsigned long irqflags;
 	int ret;
 
 	if (fw) {
@@ -5928,16 +5926,11 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
 	wlcore_adjust_conf(wl);
 
 	wl->irq = platform_get_irq(pdev, 0);
-	wl->platform_quirks = pdata->platform_quirks;
 	wl->if_ops = pdev_data->if_ops;
-
-	if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
-		irqflags = IRQF_TRIGGER_RISING;
-	else
-		irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;
+	wl->irq_flags = pdata->irq_flags;
 
 	ret = request_threaded_irq(wl->irq, NULL, wlcore_irq,
-				   irqflags, pdev->name, wl);
+				   wl->irq_flags, pdev->name, wl);
 	if (ret < 0) {
 		wl1271_error("request_irq() failed: %d", ret);
 		goto out_free_nvs;
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index 0034979..8306bde 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -185,6 +185,8 @@ struct wl1271 {
 
 	int irq;
 
+	int irq_flags;
+
 	spinlock_t wl_lock;
 
 	enum wlcore_state state;
@@ -384,9 +386,6 @@ struct wl1271 {
 	/* Quirks of specific hardware revisions */
 	unsigned int quirks;
 
-	/* Platform limitations */
-	unsigned int platform_quirks;
-
 	/* number of currently active RX BA sessions */
 	int ba_rx_session_count;
 
diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h
index b516b4f..04e3096 100644
--- a/include/linux/wl12xx.h
+++ b/include/linux/wl12xx.h
@@ -57,15 +57,12 @@ struct wl1251_platform_data {
 
 struct wl12xx_platform_data {
 	int irq;
+	unsigned long irq_flags;
 	int board_ref_clock;
 	int board_tcxo_clock;
-	unsigned long platform_quirks;
 	bool pwr_in_suspend;
 };
 
-/* Platform does not support level trigger interrupts */
-#define WL12XX_PLATFORM_QUIRK_EDGE_IRQ	BIT(0)
-
 #ifdef CONFIG_WILINK_PLATFORM_DATA
 
 int wl12xx_set_platform_data(const struct wl12xx_platform_data *data);
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 0/5] wilink: add device tree support
From: Luciano Coelho @ 2013-06-25 20:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: coelho, tony

Hi,

This patch series add device tree support to the wlcore_sdio driver,
which is used by WiLink6, WiLink7 and WiLink8.

The first patches do some clean-up to make the data needed in the
wilink device tree node smaller.  The last patch implements the actual
device tree node parsing in wlcore_sdio.

The DTS file changes will be sent separately, since they need to go
via different trees.

--
Luca.

Luciano Coelho (5):
  wl1251: split wl251 platform data to a separate structure
  wlcore: use irq_flags in pdata instead of hiding it behing a quirk
  wlcore: remove pwr_in_suspend from platform data
  wlcore: always use one-shot IRQ
  wlcore: add device tree support to the sdio module

 arch/arm/mach-davinci/board-da850-evm.c        |    2 +-
 arch/arm/mach-omap2/board-4430sdp.c            |    1 +
 arch/arm/mach-omap2/board-omap3evm.c           |    1 +
 arch/arm/mach-omap2/board-omap3pandora.c       |    4 +-
 arch/arm/mach-omap2/board-omap4panda.c         |    1 +
 arch/arm/mach-omap2/board-rx51-peripherals.c   |    2 +-
 arch/arm/mach-omap2/board-zoom-peripherals.c   |    1 +
 drivers/net/wireless/ti/wilink_platform_data.c |   37 ++++++++++--
 drivers/net/wireless/ti/wl1251/sdio.c          |   12 ++--
 drivers/net/wireless/ti/wl1251/spi.c           |    2 +-
 drivers/net/wireless/ti/wlcore/debugfs.c       |    2 +-
 drivers/net/wireless/ti/wlcore/main.c          |   16 ++---
 drivers/net/wireless/ti/wlcore/sdio.c          |   77 +++++++++++++++++++++---
 drivers/net/wireless/ti/wlcore/wlcore.h        |    5 +-
 drivers/net/wireless/ti/wlcore/wlcore_i.h      |    1 +
 include/linux/wl12xx.h                         |   28 +++++++--
 16 files changed, 147 insertions(+), 45 deletions(-)

-- 
1.7.10.4


^ permalink raw reply

* Re: pull request: bluetooth 2013-06-23
From: Pavel Machek @ 2013-06-25 20:12 UTC (permalink / raw)
  To: Gustavo Padovan, linville, linux-wireless, linux-bluetooth,
	linux-kernel
  Cc: Rafael J. Wysocki
In-Reply-To: <20130623021351.GA2327@joana>

Hi!

> Jaganath Kanakkassery (1):
>       Bluetooth: Fix invalid length check in l2cap_information_rsp()

Could we add the "3.10 vs. thinkpad x60" patch that fixes regression?
It is from Johan Hedberg...
									Pavel

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply

* Re: regression after, " ath9k_htc: Add support for mesh interfaces"
From: Thomas Pedersen @ 2013-06-25 20:05 UTC (permalink / raw)
  To: Oleksij Rempel
  Cc: ath9k-devel@lists.ath9k.org, linux-wireless@vger.kernel.org,
	Javier Cardona, Johannes Berg
In-Reply-To: <51C93538.4050304@rempel-privat.de>

On Mon, Jun 24, 2013 at 11:14 PM, Oleksij Rempel <linux@rempel-privat.de> wrote:
> Am 25.06.2013 02:54, schrieb Thomas Pedersen:
>
>> On Fri, Jun 21, 2013 at 9:56 PM, Oleksij Rempel <linux@rempel-privat.de>
>> wrote:
>>>
>>> Hi Javier,
>>>
>>> i warning after patch "ath9k_htc: Add support for mesh interfaces".
>>> I get this warning only on pc with CONFIG_MAC80211_MESH not set. Probably
>>> you missed config check some where.
>>
>>
>> Where do you hit the warning?
>>
>
> on adapter init.
> see attachment.

That warning is triggered by wiphy_verify_combinations():

                        if (WARN_ON((wiphy->interface_modes & types) != types))
                                return -EINVAL;

But before that, the mesh iftype bit is cleared in ieee80211_register_hw():

#ifndef CONFIG_MAC80211_MESH
        /* mesh depends on Kconfig, but drivers should set it if they want */
        local->hw.wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MESH_POINT);
#endif

It seems the intention was to avoid an #ifdef CONFIG_MAC80211_MESH in
every driver, but then mac80211 also has to clear the MESH_POINT bit
for each ieee80211_iface_limit? I don't really see a cleaner way of
resolving this.

Johannes?

--
Thomas

^ permalink raw reply

* Re: [RFC][PATCH] b43: replace B43_BCMA_EXTRA with modparam allhwsupport
From: Rafał Miłecki @ 2013-06-25 19:51 UTC (permalink / raw)
  To: Jonas Gorski; +Cc: linux-wireless, John W. Linville, b43-dev
In-Reply-To: <CAOiHx=mHVhg93pRyq7Qg1H9iTnScGtCUeOoxBxpeHuH6pW2XYQ@mail.gmail.com>

2013/6/25 Jonas Gorski <jogo@openwrt.org>:
> On Tue, Jun 25, 2013 at 5:34 PM, Rafał Miłecki <zajec5@gmail.com> wrote:
>> This allows enabling support for extra hardware with just a module
>> param, without kernel/module recompilation.
>>
>> Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
>> ---
>>  drivers/net/wireless/b43/Kconfig |    6 ------
>>  drivers/net/wireless/b43/main.c  |   16 ++++++++++++++--
>>  2 files changed, 14 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
>> index 3f21e0b..51ff0b1 100644
>> --- a/drivers/net/wireless/b43/Kconfig
>> +++ b/drivers/net/wireless/b43/Kconfig
>> @@ -31,12 +31,6 @@ config B43_BCMA
>>         depends on B43 && (BCMA = y || BCMA = B43)
>>         default y
>>
>> -config B43_BCMA_EXTRA
>> -       bool "Hardware support that overlaps with the brcmsmac driver"
>> -       depends on B43_BCMA
>> -       default n if BRCMSMAC
>> -       default y
>> -
>>  config B43_SSB
>>         bool
>>         depends on B43 && (SSB = y || SSB = B43)
>> diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
>> index a95b77a..583993c 100644
>> --- a/drivers/net/wireless/b43/main.c
>> +++ b/drivers/net/wireless/b43/main.c
>> @@ -113,13 +113,19 @@ static int b43_modparam_pio = 0;
>>  module_param_named(pio, b43_modparam_pio, int, 0644);
>>  MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO");
>>
>> +#ifdef CONFIG_BRCMSMAC
>
> This is only defined if BRCMSMAC is built-in, but not if it is built
> as a module; then it's CONFIG_BRCMSMAC_MODULE, which is probably not
> what you want. To easily catch both, use IS_ENABLED(CONFIG_BRCMSMAC).
>
>> +static int modparam_allhwsupport;
>> +#else
>> +static int modparam_allhwsupport = 1;
>> +#endif
>
> And since IS_ENABLED returns 0 or 1 you should be able to reduce it to one line:
>
> static int modparam_allhwsupport = !IS_ENABLED(CONFIG_BRCMSMAC);

I love learning new tricks all the time :)

-- 
Rafał

^ permalink raw reply

* [PATCH] cfg80211/mac80211: fix doc compilation warnings
From: Michael Opdenacker @ 2013-06-25 19:48 UTC (permalink / raw)
  To: johannes, davem, linux-wireless, linux-kernel; +Cc: Michael Opdenacker

This patch fixes countless "No description found for parameter"
warnings generating documentation (running "make htmldocs"),
because the comments do not match the actual prototypes in the code.

This issue didn't exist in 3.9. It may we worth fixing in 3.10
(if it's not too late).

Signed-off-by: Michael Opdenacker <michael.opdenacker@free-electrons.com>
---
 include/net/cfg80211.h | 1 +
 include/net/mac80211.h | 4 ++--
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 26b5b69..3949642 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -4153,6 +4153,7 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
  * cfg80211_crit_proto_stopped() - indicate critical protocol stopped by driver.
  *
  * @wdev: the wireless device for which critical protocol is stopped.
+ * @gfp: the type of memory to allocate (see kmalloc).
  *
  * This function can be called by the driver to indicate it has reverted
  * operation back to normal. One reason could be that the duration given
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 885898a..79f5fa7 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1235,7 +1235,7 @@ enum ieee80211_sta_rx_bandwidth {
  * struct ieee80211_sta_rates - station rate selection table
  *
  * @rcu_head: RCU head used for freeing the table on update
- * @rates: transmit rates/flags to be used by default.
+ * @rate: transmit rates/flags to be used by default.
  *	Overriding entries per-packet is possible by using cb tx control.
  */
 struct ieee80211_sta_rates {
@@ -1276,7 +1276,7 @@ struct ieee80211_sta_rates {
  *	notifications and capabilities. The value is only valid after
  *	the station moves to associated state.
  * @smps_mode: current SMPS mode (off, static or dynamic)
- * @tx_rates: rate control selection table
+ * @rates: station rate selection table
  */
 struct ieee80211_sta {
 	u32 supp_rates[IEEE80211_NUM_BANDS];
-- 
1.8.1.2


^ permalink raw reply related

* Re: [PATCH] Documentation: dt: bindings: TI WiLink modules
From: Luciano Coelho @ 2013-06-25 19:37 UTC (permalink / raw)
  To: grant.likely, linux-doc, linux-kernel, linux-wireless,
	rob.herring, devicetree-discuss
  Cc: tony, linux-omap, linux-arm-kernel
In-Reply-To: <1372149330-24335-1-git-send-email-coelho@ti.com>

(oh crap, now *really* fixed the ARM mailing list address)

On Tue, 2013-06-25 at 11:35 +0300, Luciano Coelho wrote:
> Add device tree bindings documentation for the TI WiLink modules.
> Currently only the WLAN part of the WiLink6, WiLink7 and WiLink8
> modules is supported.
> 
> Signed-off-by: Luciano Coelho <coelho@ti.com>
> ---
> 
> I created a new directory under net to contain wireless bindings documentation.
> 
> The actual implementation in the driver will follow separately.
> 
>  .../devicetree/bindings/net/wireless/ti-wilink.txt |   46 ++++++++++++++++++++
>  1 file changed, 46 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/wireless/ti-wilink.txt
> 
> diff --git a/Documentation/devicetree/bindings/net/wireless/ti-wilink.txt b/Documentation/devicetree/bindings/net/wireless/ti-wilink.txt
> new file mode 100644
> index 0000000..d8e8bfbb
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/wireless/ti-wilink.txt
> @@ -0,0 +1,46 @@
> +TI WiLink Wireless Modules Device Tree Bindings
> +===============================================
> +
> +The WiLink modules provide wireless connectivity, such as WLAN,
> +Bluetooth, FM and NFC.
> +
> +There are several different modules available, which can be grouped by
> +their generation: WiLink6, WiLink7 and WiLink8.  WiLink4 is not
> +currently supported with device tree.
> +
> +Currently, only the WLAN portion of the modules is supported with
> +device tree.
> +
> +Required properties:
> +--------------------
> +
> +- compatible: should be "ti,wilink6", "ti,wilink7" or "ti,wilink8"
> +- interrupt-parent: the interrupt controller
> +- interrupts: out-of-band WLAN interrupt
> +	See the interrupt controller's bindings documentation for
> +	detailed definition.
> +
> +Optional properties:
> +--------------------
> +
> +- refclock: the internal WLAN reference clock frequency (required for
> +  WiLink6 and WiLink7; not used for WiLink8).  Must be one of the
> +  following:
> +	0 = 19.2 MHz
> +	1 = 26.0 MHz
> +	2 = 38.4 MHz
> +	3 = 52.0 MHz
> +	4 = 38.4 MHz, XTAL
> +	5 = 26.0 MHz, XTAL
> +
> +- tcxoclock: the internal WLAN TCXO clock frequency (required for
> +  WiLink7 not used for WiLink6 and WiLink8).  Must be one of the
> +  following:
> +	0 = 19.200 MHz
> +	1 = 26.000 MHz
> +	2 = 38.400 MHz
> +	3 = 52.000 MHz
> +	4 = 16.368 MHz
> +	5 = 32.736 MHz
> +	6 = 16.800 MHz
> +	7 = 33.600 MHz

If this is okay for everyone, can I push this via my tree (which goes to
linux-wireless->net->linus)? I think it makes more sense to send the
documentation together with the patch that actually implements the DT
node parsing in the driver.

--
Luca.



^ permalink raw reply

* Re: [PATCH] Documentation: dt: bindings: TI WiLink modules
From: Luciano Coelho @ 2013-06-25 19:35 UTC (permalink / raw)
  To: grant.likely, linux-doc, linux-kernel, linux-wireless,
	rob.herring, devicetree-discuss
  Cc: tony, tony, linux-omap, linux-arm-kernel
In-Reply-To: <1372149330-24335-1-git-send-email-coelho@ti.com>

(fixed the ARM mailing list address)

On Tue, 2013-06-25 at 11:35 +0300, Luciano Coelho wrote:
> Add device tree bindings documentation for the TI WiLink modules.
> Currently only the WLAN part of the WiLink6, WiLink7 and WiLink8
> modules is supported.
> 
> Signed-off-by: Luciano Coelho <coelho@ti.com>
> ---
> 
> I created a new directory under net to contain wireless bindings documentation.
> 
> The actual implementation in the driver will follow separately.
> 
>  .../devicetree/bindings/net/wireless/ti-wilink.txt |   46 ++++++++++++++++++++
>  1 file changed, 46 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/wireless/ti-wilink.txt
> 
> diff --git a/Documentation/devicetree/bindings/net/wireless/ti-wilink.txt b/Documentation/devicetree/bindings/net/wireless/ti-wilink.txt
> new file mode 100644
> index 0000000..d8e8bfbb
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/wireless/ti-wilink.txt
> @@ -0,0 +1,46 @@
> +TI WiLink Wireless Modules Device Tree Bindings
> +===============================================
> +
> +The WiLink modules provide wireless connectivity, such as WLAN,
> +Bluetooth, FM and NFC.
> +
> +There are several different modules available, which can be grouped by
> +their generation: WiLink6, WiLink7 and WiLink8.  WiLink4 is not
> +currently supported with device tree.
> +
> +Currently, only the WLAN portion of the modules is supported with
> +device tree.
> +
> +Required properties:
> +--------------------
> +
> +- compatible: should be "ti,wilink6", "ti,wilink7" or "ti,wilink8"
> +- interrupt-parent: the interrupt controller
> +- interrupts: out-of-band WLAN interrupt
> +	See the interrupt controller's bindings documentation for
> +	detailed definition.
> +
> +Optional properties:
> +--------------------
> +
> +- refclock: the internal WLAN reference clock frequency (required for
> +  WiLink6 and WiLink7; not used for WiLink8).  Must be one of the
> +  following:
> +	0 = 19.2 MHz
> +	1 = 26.0 MHz
> +	2 = 38.4 MHz
> +	3 = 52.0 MHz
> +	4 = 38.4 MHz, XTAL
> +	5 = 26.0 MHz, XTAL
> +
> +- tcxoclock: the internal WLAN TCXO clock frequency (required for
> +  WiLink7 not used for WiLink6 and WiLink8).  Must be one of the
> +  following:
> +	0 = 19.200 MHz
> +	1 = 26.000 MHz
> +	2 = 38.400 MHz
> +	3 = 52.000 MHz
> +	4 = 16.368 MHz
> +	5 = 32.736 MHz
> +	6 = 16.800 MHz
> +	7 = 33.600 MHz

If this is okay for everyone, can I push this via my tree (which goes to
linux-wireless->net->linus)? I think it makes more sense to send the
documentation together with the patch that actually implements the DT
node parsing in the driver.

--
Luca.


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox