Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: rtlwifi rtl8192cu: unable to use channels 12 and 13 in Europe
From: Xose Vazquez Perez @ 2013-07-23 10:50 UTC (permalink / raw)
  To: linux-wireless, Larry Finger
In-Reply-To: <51C637B2.8090000@gmail.com>

On 06/23/2013 01:48 AM, Xose Vazquez Perez wrote:
> hi,
> 
> kernel 3.9.7-100.fc17.x86_64
> 
> - dmesg:
> 
> usb 2-1.5: new high-speed USB device number 16 using ehci-pci
> usb 2-1.5: New USB device found, idVendor=0bda, idProduct=8176
> usb 2-1.5: New USB device strings: Mfr=1, Product=2, SerialNumber=3
> usb 2-1.5: Product: 802.11n WLAN Adapter
> usb 2-1.5: Manufacturer: Realtek
> usb 2-1.5: SerialNumber: 00e04c000001
> rtl8192cu: Chip version 0x10
> rtl8192cu: MAC address: 00:e0:4c:07:dd:45
> rtl8192cu: Board Type 0
> rtlwifi: rx_max_size 15360, rx_urb_num 8, in_ep 1
> rtl8192cu: Loading firmware rtlwifi/rtl8192cufw.bin
> ieee80211 phy11: Selected rate control algorithm 'rtl_rc'
> rtlwifi: wireless switch is on
> cfg80211: Calling CRDA for country: ES
> cfg80211: Regulatory domain changed to country: ES
> cfg80211:   (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
> cfg80211:   (2400000 KHz - 2483500 KHz @ 40000 KHz), (N/A, 2000 mBm)
> cfg80211:   (5150000 KHz - 5250000 KHz @ 40000 KHz), (N/A, 2000 mBm)
> cfg80211:   (5250000 KHz - 5350000 KHz @ 40000 KHz), (N/A, 2000 mBm)
> cfg80211:   (5470000 KHz - 5725000 KHz @ 40000 KHz), (N/A, 2698 mBm)
> cfg80211:   (57240000 KHz - 65880000 KHz @ 2160000 KHz), (N/A, 4000 mBm)
> rtl8192cu: MAC auto ON okay!
> rtl8192cu: Tx queue select: 0x05
> IPv6: ADDRCONF(NETDEV_UP): wlan1: link is not ready
> 
> 
> - iw list:
> 
> Wiphy phy2
>         Band 1:
>                 Capabilities: 0x1862
>                         HT20/HT40
>                         Static SM Power Save
>                         RX HT20 SGI
>                         RX HT40 SGI
>                         No RX STBC
>                         Max AMSDU length: 7935 bytes
>                         DSSS/CCK HT40
>                 Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
>                 Minimum RX AMPDU time spacing: 16 usec (0x07)
>                 HT TX/RX MCS rate indexes supported: 0-7, 32
>                 Frequencies:
>                         * 2412 MHz [1] (20.0 dBm)
>                         * 2417 MHz [2] (20.0 dBm)
>                         * 2422 MHz [3] (20.0 dBm)
>                         * 2427 MHz [4] (20.0 dBm)
>                         * 2432 MHz [5] (20.0 dBm)
>                         * 2437 MHz [6] (20.0 dBm)
>                         * 2442 MHz [7] (20.0 dBm)
>                         * 2447 MHz [8] (20.0 dBm)
>                         * 2452 MHz [9] (20.0 dBm)
>                         * 2457 MHz [10] (20.0 dBm)
>                         * 2462 MHz [11] (20.0 dBm)
>                         * 2467 MHz [12] (disabled)
>                         * 2472 MHz [13] (disabled)
>                         * 2484 MHz [14] (disabled)
>                 Bitrates (non-HT):
>                         * 1.0 Mbps
>                         * 2.0 Mbps
>                         * 5.5 Mbps
>                         * 11.0 Mbps
>                         * 6.0 Mbps
>                         * 9.0 Mbps
>                         * 12.0 Mbps
>                         * 18.0 Mbps
>                         * 24.0 Mbps
>                         * 36.0 Mbps
>                         * 48.0 Mbps
>                         * 54.0 Mbps
>         max # scan SSIDs: 4
>         max scan IEs length: 2257 bytes
>         RTS threshold: 2347
>         Coverage class: 0 (up to 0m)
>         Supported Ciphers:
>                 * WEP40 (00-0f-ac:1)
>                 * WEP104 (00-0f-ac:5)
>                 * TKIP (00-0f-ac:2)
>                 * CCMP (00-0f-ac:4)
>         Available Antennas: TX 0 RX 0
>         Supported interface modes:
>                  * IBSS
>                  * managed
>                  * AP
>                  * AP/VLAN
>                  * monitor
>         software interface modes (can always be added):
>                  * AP/VLAN
>                  * monitor
>         interface combinations are not supported
>         Supported commands:
>                  * new_interface
>                  * set_interface
>                  * new_key
>                  * new_beacon
>                  * new_station
>                  * new_mpath
>                  * set_mesh_params
>                  * set_bss
>                  * authenticate
>                  * associate
>                  * deauthenticate
>                  * disassociate
>                  * join_ibss
>                  * join_mesh
>                  * set_tx_bitrate_mask
>                  * action
>                  * frame_wait_cancel
>                  * set_wiphy_netns
>                  * set_channel
>                  * set_wds_peer
>                  * Unknown command (84)
>                  * Unknown command (87)
>                  * Unknown command (85)
>                  * Unknown command (89)
>                  * Unknown command (92)
>                  * connect
>                  * disconnect
>         Supported TX frame types:
>                  * IBSS: 0x0000 0x0010 0x0020 0x0030 0x0040 0x0050 0x0060 0x0070 0x0080 0x0090 0x00a0 0x00b0 0x00c0 0x00d0 0x00e0 0x00f0
>                  * managed: 0x0000 0x0010 0x0020 0x0030 0x0040 0x0050 0x0060 0x0070 0x0080 0x0090 0x00a0 0x00b0 0x00c0 0x00d0 0x00e0 0x00f0
>                  * AP: 0x0000 0x0010 0x0020 0x0030 0x0040 0x0050 0x0060 0x0070 0x0080 0x0090 0x00a0 0x00b0 0x00c0 0x00d0 0x00e0 0x00f0
>                  * AP/VLAN: 0x0000 0x0010 0x0020 0x0030 0x0040 0x0050 0x0060 0x0070 0x0080 0x0090 0x00a0 0x00b0 0x00c0 0x00d0 0x00e0 0x00f0
>                  * mesh point: 0x0000 0x0010 0x0020 0x0030 0x0040 0x0050 0x0060 0x0070 0x0080 0x0090 0x00a0 0x00b0 0x00c0 0x00d0 0x00e0 0x00f0
>                  * P2P-client: 0x0000 0x0010 0x0020 0x0030 0x0040 0x0050 0x0060 0x0070 0x0080 0x0090 0x00a0 0x00b0 0x00c0 0x00d0 0x00e0 0x00f0
>                  * P2P-GO: 0x0000 0x0010 0x0020 0x0030 0x0040 0x0050 0x0060 0x0070 0x0080 0x0090 0x00a0 0x00b0 0x00c0 0x00d0 0x00e0 0x00f0
>                  * Unknown mode (10): 0x0000 0x0010 0x0020 0x0030 0x0040 0x0050 0x0060 0x0070 0x0080 0x0090 0x00a0 0x00b0 0x00c0 0x00d0 0x00e0 0x00f0
>         Supported RX frame types:
>                  * IBSS: 0x0040 0x00b0 0x00c0 0x00d0
>                  * managed: 0x0040 0x00d0
>                  * AP: 0x0000 0x0020 0x0040 0x00a0 0x00b0 0x00c0 0x00d0
>                  * AP/VLAN: 0x0000 0x0020 0x0040 0x00a0 0x00b0 0x00c0 0x00d0
>                  * mesh point: 0x00b0 0x00c0 0x00d0
>                  * P2P-client: 0x0040 0x00d0
>                  * P2P-GO: 0x0000 0x0020 0x0040 0x00a0 0x00b0 0x00c0 0x00d0
>                  * Unknown mode (10): 0x0040 0x00d0
>         HT Capability overrides:
>                  * MCS: ff ff ff ff ff ff ff ff ff ff
>                  * maximum A-MSDU length
>                  * supported channel width
>                  * short GI for 40 MHz
>                  * max A-MPDU length exponent
>                  * min MPDU start spacing
>         Device supports TX status socket option.
>         Device supports HT-IBSS.
> 
> 
> thank you.
> 

It also happens in 3.10.2. This time CC Larry.

thanks.

^ permalink raw reply

* Pull request: ath-current 20130723
From: Kalle Valo @ 2013-07-23  9:46 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, ath6kl-devel, ath10k

Hi John,

here's an ath6kl and ath10k pull request for 3.11-rc series.

Geert Uytterhoeven fixed an ath10k build problem when NO_DMA=y. I added
a missing MAINTAINERS entry for ath10k and updated ath6kl git tree
location.

Please let me know if there are any problems, or if you prefer me to
send them through wireless-next instead.

Kalle

The following changes since commit 64b6f46f1141ad938e354f37af62e28da972e8eb:

  ath9k_hw: Fix multicast search for AR9002 family (2013-07-18 16:22:00 -0400)

are available in the git repository at:

  git://github.com/kvalo/ath.git for-linville-current

for you to fetch changes up to 58cfb681bffb43654776a218a087028ff425ba9e:

  MAINTAINERS: update ath6kl git location (2013-07-22 12:26:12 +0300)

----------------------------------------------------------------
Geert Uytterhoeven (1):
      ath10k: ATH10K should depend on HAS_DMA

Kalle Valo (2):
      MAINTAINERS: add ath10k
      MAINTAINERS: update ath6kl git location

 MAINTAINERS                             |   10 +++++++++-
 drivers/net/wireless/ath/ath10k/Kconfig |    2 +-
 2 files changed, 10 insertions(+), 2 deletions(-)

-- 
Kalle Valo

^ permalink raw reply

* Re: [PATCH 0/2] MAINTAINERS: ath10k and ath6kl updates
From: Kalle Valo @ 2013-07-23  9:26 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath10k
In-Reply-To: <20130722093113.26562.11543.stgit@localhost6.localdomain6>

Kalle Valo <kvalo@qca.qualcomm.com> writes:

> here few patches for MAINTAINERS. If they are ok I'll add them to ath.git and
> send a pull request to John.

Applied to ath-current branch of ath.git.

-- 
Kalle Valo

^ permalink raw reply

* Re: [PATCH v2 0/4] ath10k: fixes
From: Kalle Valo @ 2013-07-23  8:47 UTC (permalink / raw)
  To: Michal Kazior; +Cc: ath10k, linux-wireless
In-Reply-To: <1374495211-20353-1-git-send-email-michal.kazior@tieto.com>

Michal Kazior <michal.kazior@tieto.com> writes:

> Hi,
>
> Here are some fixes for ath10k. The rts threshold
> patch addresses my mistake in commit
> 9aeb6fe53d1f0d6e58658484ce9ad7b59f0ef16b which
> caused rts to be always enabled causing throughput
> issues in some cases.
>
> v2: first patch is split now into two as requested
>     rebased on top of latest github master branch
>
>
> Michal Kazior (4):
>   ath10k: prevent HTC from being used after stopping
>   ath10k: don't reset HTC endpoints unnecessarily
>   ath10k: fix memleak in mac setup
>   ath10k: fix rts/fragmentation threshold setup

All four applied, thanks.

-- 
Kalle Valo

^ permalink raw reply

* Re: [PATCH v2 2/4] ath10k: don't reset HTC endpoints unnecessarily
From: Kalle Valo @ 2013-07-23  8:46 UTC (permalink / raw)
  To: Michal Kazior; +Cc: ath10k, linux-wireless
In-Reply-To: <1374495211-20353-3-git-send-email-michal.kazior@tieto.com>

Michal Kazior <michal.kazior@tieto.com> writes:

> Endpoints are re-initialized upon HTC start anyway
> so there's no need to do that twice in case of
> restarting HTC (i.e. in case of hardware
> recovery).
>
> Signed-off-by: Michal Kazior <michal.kazior@tieto.com>

This is much better, thanks.

-- 
Kalle Valo

^ permalink raw reply

* Re: [PATCH v4] ath10k: create debugfs interface to trigger fw crash
From: Kalle Valo @ 2013-07-23  8:02 UTC (permalink / raw)
  To: Michal Kazior; +Cc: ath10k, linux-wireless
In-Reply-To: <1374494931-18913-1-git-send-email-michal.kazior@tieto.com>

Michal Kazior <michal.kazior@tieto.com> writes:

> This can be useful for testing. To perform a
> forced firmware crash write 'crash' to
> 'simulate_fw_crash' debugfs file. E.g.
>
>   echo crash > /sys/kernel/debug/ieee80211/phy1/ath10k/simulate_fw_crash
>
> Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
> ---
> v3: return an appropriate errno instead of using ath10k_warn()

Thanks, applied.

-- 
Kalle Valo

^ permalink raw reply

* Re: [PATCH] Make BCMA_HOST_SOC depend on BCM47XX
From: Rafał Miłecki @ 2013-07-23  7:50 UTC (permalink / raw)
  To: Hauke Mehrtens; +Cc: John W. Linville, linux-wireless
In-Reply-To: <51EE3018.4000507@hauke-m.de>

2013/7/23 Hauke Mehrtens <hauke@hauke-m.de>:
> On 07/23/2013 04:31 AM, John W. Linville wrote:
>> From: "John W. Linville" <linville@tuxdriver.com>
>>
>> Otherwise, 'make allyesconfig' generates this:
>>
>>   CC [M]  drivers/net/ethernet/broadcom/bgmac.o
>> drivers/net/ethernet/broadcom/bgmac.c:19:27: fatal error:
>> bcm47xx_nvram.h: No such file or directory
>> compilation terminated.
>> make[4]: *** [drivers/net/ethernet/broadcom/bgmac.o] Error 1
>> make[3]: *** [drivers/net/ethernet/broadcom] Error 2
>> make[2]: *** [drivers/net/ethernet] Error 2
>> make[1]: *** [drivers/net] Error 2
>> make: *** [drivers] Error 2
>>
>> Signed-off-by: John W. Linville <linville@tuxdriver.com>
>> ---
>>  drivers/bcma/Kconfig | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig
>> index 7c081b3..a2bdab1 100644
>> --- a/drivers/bcma/Kconfig
>> +++ b/drivers/bcma/Kconfig
>> @@ -36,7 +36,7 @@ config BCMA_DRIVER_PCI_HOSTMODE
>>
>>  config BCMA_HOST_SOC
>>       bool "Support for BCMA in a SoC"
>> -     depends on BCMA
>> +     depends on BCMA && BCM47XX
>>       help
>>         Host interface for a Broadcom AIX bus directly mapped into
>>         the memory. This only works with the Broadcom SoCs from the
>>
> I think bgmac should depend on BCM47XX.

Yeah, I'm wondering about that.

It's bgmac that calls BCM47XX specific functions (nvram).

On the other hand it doesn't make much sense to use BCMA_HOST_SOC on
anything else than BCM47XX, does it?

-- 
Rafał

^ permalink raw reply

* Re: [PATCH] Make BCMA_HOST_SOC depend on BCM47XX
From: Hauke Mehrtens @ 2013-07-23  7:26 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Rafał Miłecki
In-Reply-To: <1374546675-384-1-git-send-email-linville@tuxdriver.com>

On 07/23/2013 04:31 AM, John W. Linville wrote:
> From: "John W. Linville" <linville@tuxdriver.com>
> 
> Otherwise, 'make allyesconfig' generates this:
> 
>   CC [M]  drivers/net/ethernet/broadcom/bgmac.o
> drivers/net/ethernet/broadcom/bgmac.c:19:27: fatal error:
> bcm47xx_nvram.h: No such file or directory
> compilation terminated.
> make[4]: *** [drivers/net/ethernet/broadcom/bgmac.o] Error 1
> make[3]: *** [drivers/net/ethernet/broadcom] Error 2
> make[2]: *** [drivers/net/ethernet] Error 2
> make[1]: *** [drivers/net] Error 2
> make: *** [drivers] Error 2
> 
> Signed-off-by: John W. Linville <linville@tuxdriver.com>
> ---
>  drivers/bcma/Kconfig | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig
> index 7c081b3..a2bdab1 100644
> --- a/drivers/bcma/Kconfig
> +++ b/drivers/bcma/Kconfig
> @@ -36,7 +36,7 @@ config BCMA_DRIVER_PCI_HOSTMODE
>  
>  config BCMA_HOST_SOC
>  	bool "Support for BCMA in a SoC"
> -	depends on BCMA
> +	depends on BCMA && BCM47XX
>  	help
>  	  Host interface for a Broadcom AIX bus directly mapped into
>  	  the memory. This only works with the Broadcom SoCs from the
> 
I think bgmac should depend on BCM47XX.

Hauke

^ permalink raw reply

* Re: [PATCH] ath: wil6210: Fix build error
From: Luis R. Rodriguez @ 2013-07-23  7:13 UTC (permalink / raw)
  To: Vladimir Kondratiev; +Cc: linux-wireless
In-Reply-To: <6487488.19IqyPtizJ@lx-vladimir>

On Tue, Jul 23, 2013 at 12:06 AM, Vladimir Kondratiev
<qca_vkondrat@qca.qualcomm.com> wrote:
> On Monday, July 22, 2013 09:17:01 AM Luis R. Rodriguez wrote:
>> On Sun, Jul 21, 2013 at 10:06:31AM +0300, Vladimir Kondratiev wrote:
>> > Hmm, I have no warning for this with neither 3.10 nor 3.11 kernel version; but
>> > patch is correct, and here is my
>> > Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
>>
>> If you agree with a patch you don't say you Sign-off-by it as well,
>> you say Acked-by. The Signed-off-by tag has a very specific meaning
>> from development to a maintainer's hands, and its definition is on
>> the Developer Certificate or Origin.
>>
>> So in this case Acked-by is better.
>>
>>   Luis
>
> <drop most of CC>
>
> I thought that I need to add Signed-off-by: as driver's maintainer, because
> (quote Documentation/SubmittingPatches):
> ---
> The Signed-off-by: tag indicates that the signer was involved in the
> development of the patch, or that he/she was in the patch's delivery path.
> ---
>
> This is similar to other maintainers adding its Signed-off-by:.
> Or, is driver's maintainer an exception from the rule quoted above?

If you had a git tree, sure, otherwise not in this case.

 Luis

^ permalink raw reply

* Re: [PATCH] ath: wil6210: Fix build error
From: Vladimir Kondratiev @ 2013-07-23  7:06 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: linux-wireless
In-Reply-To: <20130722161554.GR17130@pogo>

On Monday, July 22, 2013 09:17:01 AM Luis R. Rodriguez wrote:
> On Sun, Jul 21, 2013 at 10:06:31AM +0300, Vladimir Kondratiev wrote:
> > Hmm, I have no warning for this with neither 3.10 nor 3.11 kernel version; but
> > patch is correct, and here is my
> > Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
> 
> If you agree with a patch you don't say you Sign-off-by it as well,
> you say Acked-by. The Signed-off-by tag has a very specific meaning
> from development to a maintainer's hands, and its definition is on
> the Developer Certificate or Origin.
> 
> So in this case Acked-by is better.
> 
>   Luis

<drop most of CC>

I thought that I need to add Signed-off-by: as driver's maintainer, because
(quote Documentation/SubmittingPatches):
---
The Signed-off-by: tag indicates that the signer was involved in the
development of the patch, or that he/she was in the patch's delivery path.
---

This is similar to other maintainers adding its Signed-off-by:.
Or, is driver's maintainer an exception from the rule quoted above?

Thanks, Vladimir

^ permalink raw reply

* [PATCH] mwifiex: Add missing endian conversion.
From: Tomasz Moń @ 2013-07-23  5:42 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, bzhao, Tomasz Moń

Both type and pkt_len variables are in host endian and these should be in
Little Endian in the payload.

Signed-off-by: Tomasz Moń <desowin@gmail.com>
Acked-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/mwifiex/sdio.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 5ee5ed0..c9f3ecf 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -1625,8 +1625,8 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter,
 	/* Allocate buffer and copy payload */
 	blk_size = MWIFIEX_SDIO_BLOCK_SIZE;
 	buf_block_len = (pkt_len + blk_size - 1) / blk_size;
-	*(u16 *) &payload[0] = (u16) pkt_len;
-	*(u16 *) &payload[2] = type;
+	*(__le16 *)&payload[0] = cpu_to_le16((u16)pkt_len);
+	*(__le16 *)&payload[2] = cpu_to_le16(type);
 
 	/*
 	 * This is SDIO specific header
-- 
1.8.3.msysgit.0


^ permalink raw reply related

* Re: FUSB200 xhci issue
From: Oleksij Rempel @ 2013-07-23  4:59 UTC (permalink / raw)
  To: Christian Lamparter; +Cc: linux-wireless, Sarah Sharp, Seth Forshee, USB list
In-Reply-To: <3155156.7uKpoiQrxp@blech>

Am 22.07.2013 23:23, schrieb Christian Lamparter:
> On Monday, July 22, 2013 10:47:41 PM Oleksij Rempel wrote:
>> Am 22.07.2013 21:54, schrieb Christian Lamparter:
>>> Hello!
>>>
>>> On Monday, July 22, 2013 05:21:54 PM Oleksij Rempel wrote:
>>>> i'm one of ath9k_htc devs. Currently i'm working on usb_suspend issue of
>>>> this adapters. Looks like ar9271 and ar7010 have FUSB200, and i
>>>> accidentally discovered that 9170 have it too. Are there any issue with
>>>> usb-suspend + xhci controllers by you? Did you some how specially
>>>> handled it?
>>>
>>> No, I haven't heard any complains about xhci + suspend. In fact,
>>> it's working fine with the NEC xhci I have. I also have a AR9271
>>> and AR7010, so if you want I could try if they survive a suspend
>>> +resume cycle when attached.
>>>
>>> But, I do have a bug-report from someone else who has/had? problems
>>> with carl9170 and xhci. If you want, you can get the details from:
>>> "carl9170 A-MPDU transmit problem":
>>> <http://comments.gmane.org/gmane.linux.kernel.wireless.general/104597>
>>>
>>> The likely cause is related to Intel's xhci silicon (Ivy Bridge is
>>> affected, but I don't know about Haswell):
>>> <http://permalink.gmane.org/gmane.linux.kernel.wireless.general/104602>
>>
>> Same situation is here - i have problem on Ivy Bridge.
> (Note: I don't have any Ivy Bridge system. Just Sandy Bridge
> and AMD's new A6-1450 Temash and both xhci work. So I can't
> do any proper comparisons like you.)
>
>> Steps to reproduce:
>> - plug adapter. Module and firmware will be loaded
>> - make sure usb autosupend is enabled. By default it is not! Use
>> powertop or directly sysfs to enable autosuspend for this device
>> - rmmod .... and wait some seconds until adapter is suspended and then
>> modprobe ath9k_htc

>> first packet which is bigger as 64Byte will kill EP4 FIFO. Size register
>> will report wrong size.. bigger as FIFO can handle. And only first ~40
>> readet bytes will be actually OK.. all the rest of packet will be trashed.
>
> This is what happens with a WN721 (ar9271):
>
> [17619.597905] usbcore: deregistering interface driver ath9k_htc
> [17619.679549] usb 2-2: ath9k_htc: USB layer deinitialized
> [17619.679602] ath9k_htc: Driver unloaded
> <suspend>
>
> <resume>
> [17667.543024] usb 2-2: reset high-speed USB device number 3 using xhci_hcd <----
> [17667.572168] xhci_hcd 0000:19:00.0: xHCI xhci_drop_endpoint called with disabled ep ffff88031aa77600
> [17667.572174] xhci_hcd 0000:19:00.0: xHCI xhci_drop_endpoint called with disabled ep ffff88031aa77640
> [17667.572177] xhci_hcd 0000:19:00.0: xHCI xhci_drop_endpoint called with disabled ep ffff88031aa77680
> [17667.572180] xhci_hcd 0000:19:00.0: xHCI xhci_drop_endpoint called with disabled ep ffff88031aa776c0
> [17667.572183] xhci_hcd 0000:19:00.0: xHCI xhci_drop_endpoint called with disabled ep ffff88031aa77700
> [17667.572185] xhci_hcd 0000:19:00.0: xHCI xhci_drop_endpoint called with disabled ep ffff88031aa77740
> [17667.573826] usb 2-2: ath9k_htc: Firmware htc_9271.fw requested
> [17667.573873] usbcore: registered new interface driver ath9k_htc
> [17668.038200] usb 2-2: ath9k_htc: Transferred FW: htc_9271.fw, size: 51272
> [17668.273249] ath9k_htc 2-2:1.0: ath9k_htc: HTC initialized with 33 credits
>
> The driver loads, but there's no "wlanX" interface, no phyX interface
> and the driver can't be unloaded due to "Error: Module ath9k_htc is in use".

So, it is exactly this bug.
After firmware was loaded ath9k trying to set some registers. Since 
command buffer is trashed it will write some nonsense to registers and 
some times in wrong to wrong addresses. I have some patches to do crc 
check of commands, to easy detect corrupted ones.

You reproduced it on NEC xhci? Is it possible to reproduce it in 
carl9170? How about "carl9170 A-MPDU transmit problem"?

I noticed one more workaround. By reducing skb size to 64byte for EP4, 
this bug can be avoided. But, since it works on EHCI, and on XHCI before 
usb-suspend, i would prefer to fix host controller driver.

-- 
Regards,
Oleksij

^ permalink raw reply

* [PATCH] Make BCMA_HOST_SOC depend on BCM47XX
From: John W. Linville @ 2013-07-23  2:31 UTC (permalink / raw)
  To: linux-wireless; +Cc: Rafał Miłecki, John W. Linville

From: "John W. Linville" <linville@tuxdriver.com>

Otherwise, 'make allyesconfig' generates this:

  CC [M]  drivers/net/ethernet/broadcom/bgmac.o
drivers/net/ethernet/broadcom/bgmac.c:19:27: fatal error:
bcm47xx_nvram.h: No such file or directory
compilation terminated.
make[4]: *** [drivers/net/ethernet/broadcom/bgmac.o] Error 1
make[3]: *** [drivers/net/ethernet/broadcom] Error 2
make[2]: *** [drivers/net/ethernet] Error 2
make[1]: *** [drivers/net] Error 2
make: *** [drivers] Error 2

Signed-off-by: John W. Linville <linville@tuxdriver.com>
---
 drivers/bcma/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig
index 7c081b3..a2bdab1 100644
--- a/drivers/bcma/Kconfig
+++ b/drivers/bcma/Kconfig
@@ -36,7 +36,7 @@ config BCMA_DRIVER_PCI_HOSTMODE
 
 config BCMA_HOST_SOC
 	bool "Support for BCMA in a SoC"
-	depends on BCMA
+	depends on BCMA && BCM47XX
 	help
 	  Host interface for a Broadcom AIX bus directly mapped into
 	  the memory. This only works with the Broadcom SoCs from the
-- 
1.8.1.4


^ permalink raw reply related

* [PATCH 19/21] mwifiex: code rearrangement in sdio.c
From: Bing Zhao @ 2013-07-23  2:17 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Amitkumar Karwar, Avinash Patil,
	Yogesh Ashok Powar, Nishant Sarmukadam, Frank Huang, Bing Zhao
In-Reply-To: <1374545878-15683-1-git-send-email-bzhao@marvell.com>

From: Amitkumar Karwar <akarwar@marvell.com>

Some function definitions are moved to appropriate place
to avoid forward declarations.

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/mwifiex/sdio.c | 211 ++++++++++++++++++------------------
 1 file changed, 104 insertions(+), 107 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index c32a735..1eb5efa1 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -50,9 +50,6 @@ static struct mwifiex_if_ops sdio_ops;
 
 static struct semaphore add_remove_card_sem;
 
-static int mwifiex_sdio_resume(struct device *dev);
-static void mwifiex_sdio_interrupt(struct sdio_func *func);
-
 /*
  * SDIO probe.
  *
@@ -113,6 +110,51 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
 }
 
 /*
+ * SDIO resume.
+ *
+ * Kernel needs to suspend all functions separately. Therefore all
+ * registered functions must have drivers with suspend and resume
+ * methods. Failing that the kernel simply removes the whole card.
+ *
+ * If already not resumed, this function turns on the traffic and
+ * sends a host sleep cancel request to the firmware.
+ */
+static int mwifiex_sdio_resume(struct device *dev)
+{
+	struct sdio_func *func = dev_to_sdio_func(dev);
+	struct sdio_mmc_card *card;
+	struct mwifiex_adapter *adapter;
+	mmc_pm_flag_t pm_flag = 0;
+
+	if (func) {
+		pm_flag = sdio_get_host_pm_caps(func);
+		card = sdio_get_drvdata(func);
+		if (!card || !card->adapter) {
+			pr_err("resume: invalid card or adapter\n");
+			return 0;
+		}
+	} else {
+		pr_err("resume: sdio_func is not specified\n");
+		return 0;
+	}
+
+	adapter = card->adapter;
+
+	if (!adapter->is_suspended) {
+		dev_warn(adapter->dev, "device already resumed\n");
+		return 0;
+	}
+
+	adapter->is_suspended = false;
+
+	/* Disable Host Sleep */
+	mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
+			  MWIFIEX_ASYNC_CMD);
+
+	return 0;
+}
+
+/*
  * SDIO remove.
  *
  * This function removes the interface and frees up the card structure.
@@ -212,51 +254,6 @@ static int mwifiex_sdio_suspend(struct device *dev)
 	return ret;
 }
 
-/*
- * SDIO resume.
- *
- * Kernel needs to suspend all functions separately. Therefore all
- * registered functions must have drivers with suspend and resume
- * methods. Failing that the kernel simply removes the whole card.
- *
- * If already not resumed, this function turns on the traffic and
- * sends a host sleep cancel request to the firmware.
- */
-static int mwifiex_sdio_resume(struct device *dev)
-{
-	struct sdio_func *func = dev_to_sdio_func(dev);
-	struct sdio_mmc_card *card;
-	struct mwifiex_adapter *adapter;
-	mmc_pm_flag_t pm_flag = 0;
-
-	if (func) {
-		pm_flag = sdio_get_host_pm_caps(func);
-		card = sdio_get_drvdata(func);
-		if (!card || !card->adapter) {
-			pr_err("resume: invalid card or adapter\n");
-			return 0;
-		}
-	} else {
-		pr_err("resume: sdio_func is not specified\n");
-		return 0;
-	}
-
-	adapter = card->adapter;
-
-	if (!adapter->is_suspended) {
-		dev_warn(adapter->dev, "device already resumed\n");
-		return 0;
-	}
-
-	adapter->is_suspended = false;
-
-	/* Disable Host Sleep */
-	mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
-			  MWIFIEX_ASYNC_CMD);
-
-	return 0;
-}
-
 /* Device ID for SD8786 */
 #define SDIO_DEVICE_ID_MARVELL_8786   (0x9116)
 /* Device ID for SD8787 */
@@ -707,6 +704,65 @@ static void mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter)
 }
 
 /*
+ * This function reads the interrupt status from card.
+ */
+static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
+{
+	struct sdio_mmc_card *card = adapter->card;
+	u8 sdio_ireg;
+	unsigned long flags;
+
+	if (mwifiex_read_data_sync(adapter, card->mp_regs,
+				   card->reg->max_mp_regs,
+				   REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK, 0)) {
+		dev_err(adapter->dev, "read mp_regs failed\n");
+		return;
+	}
+
+	sdio_ireg = card->mp_regs[HOST_INTSTATUS_REG];
+	if (sdio_ireg) {
+		/*
+		 * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
+		 * For SDIO new mode CMD port interrupts
+		 *	DN_LD_CMD_PORT_HOST_INT_STATUS and/or
+		 *	UP_LD_CMD_PORT_HOST_INT_STATUS
+		 * Clear the interrupt status register
+		 */
+		dev_dbg(adapter->dev, "int: sdio_ireg = %#x\n", sdio_ireg);
+		spin_lock_irqsave(&adapter->int_lock, flags);
+		adapter->int_status |= sdio_ireg;
+		spin_unlock_irqrestore(&adapter->int_lock, flags);
+	}
+}
+
+/*
+ * SDIO interrupt handler.
+ *
+ * This function reads the interrupt status from firmware and handles
+ * the interrupt in current thread (ksdioirqd) right away.
+ */
+static void
+mwifiex_sdio_interrupt(struct sdio_func *func)
+{
+	struct mwifiex_adapter *adapter;
+	struct sdio_mmc_card *card;
+
+	card = sdio_get_drvdata(func);
+	if (!card || !card->adapter) {
+		pr_debug("int: func=%p card=%p adapter=%p\n",
+			 func, card, card ? card->adapter : NULL);
+		return;
+	}
+	adapter = card->adapter;
+
+	if (!adapter->pps_uapsd_mode && adapter->ps_state == PS_STATE_SLEEP)
+		adapter->ps_state = PS_STATE_AWAKE;
+
+	mwifiex_interrupt_status(adapter);
+	mwifiex_main_process(adapter);
+}
+
+/*
  * This function enables the host interrupt.
  *
  * The host interrupt enable mask is written to the card
@@ -963,65 +1019,6 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
 }
 
 /*
- * This function reads the interrupt status from card.
- */
-static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
-{
-	struct sdio_mmc_card *card = adapter->card;
-	u8 sdio_ireg;
-	unsigned long flags;
-
-	if (mwifiex_read_data_sync(adapter, card->mp_regs,
-				   card->reg->max_mp_regs,
-				   REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK, 0)) {
-		dev_err(adapter->dev, "read mp_regs failed\n");
-		return;
-	}
-
-	sdio_ireg = card->mp_regs[HOST_INTSTATUS_REG];
-	if (sdio_ireg) {
-		/*
-		 * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
-		 * For SDIO new mode CMD port interrupts
-		 *	DN_LD_CMD_PORT_HOST_INT_STATUS and/or
-		 *	UP_LD_CMD_PORT_HOST_INT_STATUS
-		 * Clear the interrupt status register
-		 */
-		dev_dbg(adapter->dev, "int: sdio_ireg = %#x\n", sdio_ireg);
-		spin_lock_irqsave(&adapter->int_lock, flags);
-		adapter->int_status |= sdio_ireg;
-		spin_unlock_irqrestore(&adapter->int_lock, flags);
-	}
-}
-
-/*
- * SDIO interrupt handler.
- *
- * This function reads the interrupt status from firmware and handles
- * the interrupt in current thread (ksdioirqd) right away.
- */
-static void
-mwifiex_sdio_interrupt(struct sdio_func *func)
-{
-	struct mwifiex_adapter *adapter;
-	struct sdio_mmc_card *card;
-
-	card = sdio_get_drvdata(func);
-	if (!card || !card->adapter) {
-		pr_debug("int: func=%p card=%p adapter=%p\n",
-			 func, card, card ? card->adapter : NULL);
-		return;
-	}
-	adapter = card->adapter;
-
-	if (!adapter->pps_uapsd_mode && adapter->ps_state == PS_STATE_SLEEP)
-		adapter->ps_state = PS_STATE_AWAKE;
-
-	mwifiex_interrupt_status(adapter);
-	mwifiex_main_process(adapter);
-}
-
-/*
  * This function decodes a received packet.
  *
  * Based on the type, the packet is treated as either a data, or
-- 
1.8.2.3


^ permalink raw reply related

* [PATCH 16/21] mwifiex: replace mdelay with msleep
From: Bing Zhao @ 2013-07-23  2:17 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Amitkumar Karwar, Avinash Patil,
	Yogesh Ashok Powar, Nishant Sarmukadam, Frank Huang, Bing Zhao
In-Reply-To: <1374545878-15683-1-git-send-email-bzhao@marvell.com>

From: Amitkumar Karwar <akarwar@marvell.com>

It is observed that when wrong firmware is downloaded for
PCIe card, system hangs for 10 seconds. The reason is mdelay()
is used when firmware status is polled.

Replace mdelay with msleep(non-blocking API) to fix the issue.

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/mwifiex/pcie.c | 2 +-
 drivers/net/wireless/mwifiex/sdio.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index dce6486..098153f 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -1942,7 +1942,7 @@ mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num)
 			ret = 0;
 			break;
 		} else {
-			mdelay(100);
+			msleep(100);
 			ret = -1;
 		}
 	}
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 5ef49f2..c32a735 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -944,7 +944,7 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
 			ret = 0;
 			break;
 		} else {
-			mdelay(100);
+			msleep(100);
 			ret = -1;
 		}
 	}
-- 
1.8.2.3


^ permalink raw reply related

* [PATCH 20/21] mwifiex: remove duplicate structure host_cmd_tlv
From: Bing Zhao @ 2013-07-23  2:17 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Amitkumar Karwar, Avinash Patil,
	Yogesh Ashok Powar, Nishant Sarmukadam, Frank Huang, Bing Zhao
In-Reply-To: <1374545878-15683-1-git-send-email-bzhao@marvell.com>

From: Amitkumar Karwar <akarwar@marvell.com>

We already have 'struct mwifiex_ie_types_header' with same
definition. Hence host_cmd_tlv is removed in this patch.

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/mwifiex/fw.h      |  41 +++++------
 drivers/net/wireless/mwifiex/ie.c      |   2 +-
 drivers/net/wireless/mwifiex/sta_cmd.c |   5 +-
 drivers/net/wireless/mwifiex/uap_cmd.c | 130 +++++++++++++++++----------------
 4 files changed, 91 insertions(+), 87 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 99c2729..c0dfc4d 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -1366,11 +1366,6 @@ struct host_cmd_ds_802_11_eeprom_access {
 	u8 value;
 } __packed;
 
-struct host_cmd_tlv {
-	__le16 type;
-	__le16 len;
-} __packed;
-
 struct mwifiex_assoc_event {
 	u8 sta_addr[ETH_ALEN];
 	__le16 type;
@@ -1396,99 +1391,99 @@ struct host_cmd_11ac_vht_cfg {
 } __packed;
 
 struct host_cmd_tlv_akmp {
-	struct host_cmd_tlv tlv;
+	struct mwifiex_ie_types_header header;
 	__le16 key_mgmt;
 	__le16 key_mgmt_operation;
 } __packed;
 
 struct host_cmd_tlv_pwk_cipher {
-	struct host_cmd_tlv tlv;
+	struct mwifiex_ie_types_header header;
 	__le16 proto;
 	u8 cipher;
 	u8 reserved;
 } __packed;
 
 struct host_cmd_tlv_gwk_cipher {
-	struct host_cmd_tlv tlv;
+	struct mwifiex_ie_types_header header;
 	u8 cipher;
 	u8 reserved;
 } __packed;
 
 struct host_cmd_tlv_passphrase {
-	struct host_cmd_tlv tlv;
+	struct mwifiex_ie_types_header header;
 	u8 passphrase[0];
 } __packed;
 
 struct host_cmd_tlv_wep_key {
-	struct host_cmd_tlv tlv;
+	struct mwifiex_ie_types_header header;
 	u8 key_index;
 	u8 is_default;
 	u8 key[1];
 };
 
 struct host_cmd_tlv_auth_type {
-	struct host_cmd_tlv tlv;
+	struct mwifiex_ie_types_header header;
 	u8 auth_type;
 } __packed;
 
 struct host_cmd_tlv_encrypt_protocol {
-	struct host_cmd_tlv tlv;
+	struct mwifiex_ie_types_header header;
 	__le16 proto;
 } __packed;
 
 struct host_cmd_tlv_ssid {
-	struct host_cmd_tlv tlv;
+	struct mwifiex_ie_types_header header;
 	u8 ssid[0];
 } __packed;
 
 struct host_cmd_tlv_rates {
-	struct host_cmd_tlv tlv;
+	struct mwifiex_ie_types_header header;
 	u8 rates[0];
 } __packed;
 
 struct host_cmd_tlv_bcast_ssid {
-	struct host_cmd_tlv tlv;
+	struct mwifiex_ie_types_header header;
 	u8 bcast_ctl;
 } __packed;
 
 struct host_cmd_tlv_beacon_period {
-	struct host_cmd_tlv tlv;
+	struct mwifiex_ie_types_header header;
 	__le16 period;
 } __packed;
 
 struct host_cmd_tlv_dtim_period {
-	struct host_cmd_tlv tlv;
+	struct mwifiex_ie_types_header header;
 	u8 period;
 } __packed;
 
 struct host_cmd_tlv_frag_threshold {
-	struct host_cmd_tlv tlv;
+	struct mwifiex_ie_types_header header;
 	__le16 frag_thr;
 } __packed;
 
 struct host_cmd_tlv_rts_threshold {
-	struct host_cmd_tlv tlv;
+	struct mwifiex_ie_types_header header;
 	__le16 rts_thr;
 } __packed;
 
 struct host_cmd_tlv_retry_limit {
-	struct host_cmd_tlv tlv;
+	struct mwifiex_ie_types_header header;
 	u8 limit;
 } __packed;
 
 struct host_cmd_tlv_mac_addr {
-	struct host_cmd_tlv tlv;
+	struct mwifiex_ie_types_header header;
 	u8 mac_addr[ETH_ALEN];
 } __packed;
 
 struct host_cmd_tlv_channel_band {
-	struct host_cmd_tlv tlv;
+	struct mwifiex_ie_types_header header;
 	u8 band_config;
 	u8 channel;
 } __packed;
 
 struct host_cmd_tlv_ageout_timer {
-	struct host_cmd_tlv tlv;
+	struct mwifiex_ie_types_header header;
 	__le32 sta_ao_timer;
 } __packed;
 
diff --git a/drivers/net/wireless/mwifiex/ie.c b/drivers/net/wireless/mwifiex/ie.c
index e38342f..220af4f 100644
--- a/drivers/net/wireless/mwifiex/ie.c
+++ b/drivers/net/wireless/mwifiex/ie.c
@@ -87,7 +87,7 @@ mwifiex_update_autoindex_ies(struct mwifiex_private *priv,
 	u8 *tmp;
 
 	input_len = le16_to_cpu(ie_list->len);
-	travel_len = sizeof(struct host_cmd_tlv);
+	travel_len = sizeof(struct mwifiex_ie_types_header);
 
 	ie_list->len = 0;
 
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index 8ece485..9b75ed8 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -707,8 +707,9 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
 		if (priv->bss_type == MWIFIEX_BSS_TYPE_UAP) {
 			tlv_mac = (void *)((u8 *)&key_material->key_param_set +
 					   key_param_len);
-			tlv_mac->tlv.type = cpu_to_le16(TLV_TYPE_STA_MAC_ADDR);
-			tlv_mac->tlv.len = cpu_to_le16(ETH_ALEN);
+			tlv_mac->header.type =
+					cpu_to_le16(TLV_TYPE_STA_MAC_ADDR);
+			tlv_mac->header.len = cpu_to_le16(ETH_ALEN);
 			memcpy(tlv_mac->mac_addr, enc_key->mac_addr, ETH_ALEN);
 			cmd_size = key_param_len + S_DS_GEN +
 				   sizeof(key_material->action) +
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index 2de882d..64424c8 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -293,9 +293,9 @@ mwifiex_uap_bss_wpa(u8 **tlv_buf, void *cmd_buf, u16 *param_size)
 	u8 *tlv = *tlv_buf;
 
 	tlv_akmp = (struct host_cmd_tlv_akmp *)tlv;
-	tlv_akmp->tlv.type = cpu_to_le16(TLV_TYPE_UAP_AKMP);
-	tlv_akmp->tlv.len = cpu_to_le16(sizeof(struct host_cmd_tlv_akmp) -
-					sizeof(struct host_cmd_tlv));
+	tlv_akmp->header.type = cpu_to_le16(TLV_TYPE_UAP_AKMP);
+	tlv_akmp->header.len = cpu_to_le16(sizeof(struct host_cmd_tlv_akmp) -
+					sizeof(struct mwifiex_ie_types_header));
 	tlv_akmp->key_mgmt_operation = cpu_to_le16(bss_cfg->key_mgmt_operation);
 	tlv_akmp->key_mgmt = cpu_to_le16(bss_cfg->key_mgmt);
 	cmd_size += sizeof(struct host_cmd_tlv_akmp);
@@ -303,10 +303,10 @@ mwifiex_uap_bss_wpa(u8 **tlv_buf, void *cmd_buf, u16 *param_size)
 
 	if (bss_cfg->wpa_cfg.pairwise_cipher_wpa & VALID_CIPHER_BITMAP) {
 		pwk_cipher = (struct host_cmd_tlv_pwk_cipher *)tlv;
-		pwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_PWK_CIPHER);
-		pwk_cipher->tlv.len =
+		pwk_cipher->header.type = cpu_to_le16(TLV_TYPE_PWK_CIPHER);
+		pwk_cipher->header.len =
 			cpu_to_le16(sizeof(struct host_cmd_tlv_pwk_cipher) -
-				    sizeof(struct host_cmd_tlv));
+				    sizeof(struct mwifiex_ie_types_header));
 		pwk_cipher->proto = cpu_to_le16(PROTOCOL_WPA);
 		pwk_cipher->cipher = bss_cfg->wpa_cfg.pairwise_cipher_wpa;
 		cmd_size += sizeof(struct host_cmd_tlv_pwk_cipher);
@@ -315,10 +315,10 @@ mwifiex_uap_bss_wpa(u8 **tlv_buf, void *cmd_buf, u16 *param_size)
 
 	if (bss_cfg->wpa_cfg.pairwise_cipher_wpa2 & VALID_CIPHER_BITMAP) {
 		pwk_cipher = (struct host_cmd_tlv_pwk_cipher *)tlv;
-		pwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_PWK_CIPHER);
-		pwk_cipher->tlv.len =
+		pwk_cipher->header.type = cpu_to_le16(TLV_TYPE_PWK_CIPHER);
+		pwk_cipher->header.len =
 			cpu_to_le16(sizeof(struct host_cmd_tlv_pwk_cipher) -
-				    sizeof(struct host_cmd_tlv));
+				    sizeof(struct mwifiex_ie_types_header));
 		pwk_cipher->proto = cpu_to_le16(PROTOCOL_WPA2);
 		pwk_cipher->cipher = bss_cfg->wpa_cfg.pairwise_cipher_wpa2;
 		cmd_size += sizeof(struct host_cmd_tlv_pwk_cipher);
@@ -327,10 +327,10 @@ mwifiex_uap_bss_wpa(u8 **tlv_buf, void *cmd_buf, u16 *param_size)
 
 	if (bss_cfg->wpa_cfg.group_cipher & VALID_CIPHER_BITMAP) {
 		gwk_cipher = (struct host_cmd_tlv_gwk_cipher *)tlv;
-		gwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_GWK_CIPHER);
-		gwk_cipher->tlv.len =
+		gwk_cipher->header.type = cpu_to_le16(TLV_TYPE_GWK_CIPHER);
+		gwk_cipher->header.len =
 			cpu_to_le16(sizeof(struct host_cmd_tlv_gwk_cipher) -
-				    sizeof(struct host_cmd_tlv));
+				    sizeof(struct mwifiex_ie_types_header));
 		gwk_cipher->cipher = bss_cfg->wpa_cfg.group_cipher;
 		cmd_size += sizeof(struct host_cmd_tlv_gwk_cipher);
 		tlv += sizeof(struct host_cmd_tlv_gwk_cipher);
@@ -338,13 +338,15 @@ mwifiex_uap_bss_wpa(u8 **tlv_buf, void *cmd_buf, u16 *param_size)
 
 	if (bss_cfg->wpa_cfg.length) {
 		passphrase = (struct host_cmd_tlv_passphrase *)tlv;
-		passphrase->tlv.type = cpu_to_le16(TLV_TYPE_UAP_WPA_PASSPHRASE);
-		passphrase->tlv.len = cpu_to_le16(bss_cfg->wpa_cfg.length);
+		passphrase->header.type =
+				cpu_to_le16(TLV_TYPE_UAP_WPA_PASSPHRASE);
+		passphrase->header.len = cpu_to_le16(bss_cfg->wpa_cfg.length);
 		memcpy(passphrase->passphrase, bss_cfg->wpa_cfg.passphrase,
 		       bss_cfg->wpa_cfg.length);
-		cmd_size += sizeof(struct host_cmd_tlv) +
+		cmd_size += sizeof(struct mwifiex_ie_types_header) +
 			    bss_cfg->wpa_cfg.length;
-		tlv += sizeof(struct host_cmd_tlv) + bss_cfg->wpa_cfg.length;
+		tlv += sizeof(struct mwifiex_ie_types_header) +
+				bss_cfg->wpa_cfg.length;
 	}
 
 	*param_size = cmd_size;
@@ -403,16 +405,17 @@ mwifiex_uap_bss_wep(u8 **tlv_buf, void *cmd_buf, u16 *param_size)
 		    (bss_cfg->wep_cfg[i].length == WLAN_KEY_LEN_WEP40 ||
 		     bss_cfg->wep_cfg[i].length == WLAN_KEY_LEN_WEP104)) {
 			wep_key = (struct host_cmd_tlv_wep_key *)tlv;
-			wep_key->tlv.type = cpu_to_le16(TLV_TYPE_UAP_WEP_KEY);
-			wep_key->tlv.len =
+			wep_key->header.type =
+				cpu_to_le16(TLV_TYPE_UAP_WEP_KEY);
+			wep_key->header.len =
 				cpu_to_le16(bss_cfg->wep_cfg[i].length + 2);
 			wep_key->key_index = bss_cfg->wep_cfg[i].key_index;
 			wep_key->is_default = bss_cfg->wep_cfg[i].is_default;
 			memcpy(wep_key->key, bss_cfg->wep_cfg[i].key,
 			       bss_cfg->wep_cfg[i].length);
-			cmd_size += sizeof(struct host_cmd_tlv) + 2 +
+			cmd_size += sizeof(struct mwifiex_ie_types_header) + 2 +
 				    bss_cfg->wep_cfg[i].length;
-			tlv += sizeof(struct host_cmd_tlv) + 2 +
+			tlv += sizeof(struct mwifiex_ie_types_header) + 2 +
 				    bss_cfg->wep_cfg[i].length;
 		}
 	}
@@ -449,16 +452,17 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
 
 	if (bss_cfg->ssid.ssid_len) {
 		ssid = (struct host_cmd_tlv_ssid *)tlv;
-		ssid->tlv.type = cpu_to_le16(TLV_TYPE_UAP_SSID);
-		ssid->tlv.len = cpu_to_le16((u16)bss_cfg->ssid.ssid_len);
+		ssid->header.type = cpu_to_le16(TLV_TYPE_UAP_SSID);
+		ssid->header.len = cpu_to_le16((u16)bss_cfg->ssid.ssid_len);
 		memcpy(ssid->ssid, bss_cfg->ssid.ssid, bss_cfg->ssid.ssid_len);
-		cmd_size += sizeof(struct host_cmd_tlv) +
+		cmd_size += sizeof(struct mwifiex_ie_types_header) +
 			    bss_cfg->ssid.ssid_len;
-		tlv += sizeof(struct host_cmd_tlv) + bss_cfg->ssid.ssid_len;
+		tlv += sizeof(struct mwifiex_ie_types_header) +
+				bss_cfg->ssid.ssid_len;
 
 		bcast_ssid = (struct host_cmd_tlv_bcast_ssid *)tlv;
-		bcast_ssid->tlv.type = cpu_to_le16(TLV_TYPE_UAP_BCAST_SSID);
-		bcast_ssid->tlv.len =
+		bcast_ssid->header.type = cpu_to_le16(TLV_TYPE_UAP_BCAST_SSID);
+		bcast_ssid->header.len =
 				cpu_to_le16(sizeof(bcast_ssid->bcast_ctl));
 		bcast_ssid->bcast_ctl = bss_cfg->bcast_ssid_ctl;
 		cmd_size += sizeof(struct host_cmd_tlv_bcast_ssid);
@@ -466,13 +470,13 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
 	}
 	if (bss_cfg->rates[0]) {
 		tlv_rates = (struct host_cmd_tlv_rates *)tlv;
-		tlv_rates->tlv.type = cpu_to_le16(TLV_TYPE_UAP_RATES);
+		tlv_rates->header.type = cpu_to_le16(TLV_TYPE_UAP_RATES);
 
 		for (i = 0; i < MWIFIEX_SUPPORTED_RATES && bss_cfg->rates[i];
 		     i++)
 			tlv_rates->rates[i] = bss_cfg->rates[i];
 
-		tlv_rates->tlv.len = cpu_to_le16(i);
+		tlv_rates->header.len = cpu_to_le16(i);
 		cmd_size += sizeof(struct host_cmd_tlv_rates) + i;
 		tlv += sizeof(struct host_cmd_tlv_rates) + i;
 	}
@@ -482,10 +486,10 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
 	    (bss_cfg->band_cfg == BAND_CONFIG_A &&
 	     bss_cfg->channel <= MAX_CHANNEL_BAND_A))) {
 		chan_band = (struct host_cmd_tlv_channel_band *)tlv;
-		chan_band->tlv.type = cpu_to_le16(TLV_TYPE_CHANNELBANDLIST);
-		chan_band->tlv.len =
+		chan_band->header.type = cpu_to_le16(TLV_TYPE_CHANNELBANDLIST);
+		chan_band->header.len =
 			cpu_to_le16(sizeof(struct host_cmd_tlv_channel_band) -
-				    sizeof(struct host_cmd_tlv));
+				    sizeof(struct mwifiex_ie_types_header));
 		chan_band->band_config = bss_cfg->band_cfg;
 		chan_band->channel = bss_cfg->channel;
 		cmd_size += sizeof(struct host_cmd_tlv_channel_band);
@@ -494,11 +498,11 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
 	if (bss_cfg->beacon_period >= MIN_BEACON_PERIOD &&
 	    bss_cfg->beacon_period <= MAX_BEACON_PERIOD) {
 		beacon_period = (struct host_cmd_tlv_beacon_period *)tlv;
-		beacon_period->tlv.type =
+		beacon_period->header.type =
 					cpu_to_le16(TLV_TYPE_UAP_BEACON_PERIOD);
-		beacon_period->tlv.len =
+		beacon_period->header.len =
 			cpu_to_le16(sizeof(struct host_cmd_tlv_beacon_period) -
-				    sizeof(struct host_cmd_tlv));
+				    sizeof(struct mwifiex_ie_types_header));
 		beacon_period->period = cpu_to_le16(bss_cfg->beacon_period);
 		cmd_size += sizeof(struct host_cmd_tlv_beacon_period);
 		tlv += sizeof(struct host_cmd_tlv_beacon_period);
@@ -506,21 +510,22 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
 	if (bss_cfg->dtim_period >= MIN_DTIM_PERIOD &&
 	    bss_cfg->dtim_period <= MAX_DTIM_PERIOD) {
 		dtim_period = (struct host_cmd_tlv_dtim_period *)tlv;
-		dtim_period->tlv.type = cpu_to_le16(TLV_TYPE_UAP_DTIM_PERIOD);
-		dtim_period->tlv.len =
+		dtim_period->header.type =
+			cpu_to_le16(TLV_TYPE_UAP_DTIM_PERIOD);
+		dtim_period->header.len =
 			cpu_to_le16(sizeof(struct host_cmd_tlv_dtim_period) -
-				    sizeof(struct host_cmd_tlv));
+				    sizeof(struct mwifiex_ie_types_header));
 		dtim_period->period = bss_cfg->dtim_period;
 		cmd_size += sizeof(struct host_cmd_tlv_dtim_period);
 		tlv += sizeof(struct host_cmd_tlv_dtim_period);
 	}
 	if (bss_cfg->rts_threshold <= MWIFIEX_RTS_MAX_VALUE) {
 		rts_threshold = (struct host_cmd_tlv_rts_threshold *)tlv;
-		rts_threshold->tlv.type =
+		rts_threshold->header.type =
 					cpu_to_le16(TLV_TYPE_UAP_RTS_THRESHOLD);
-		rts_threshold->tlv.len =
+		rts_threshold->header.len =
 			cpu_to_le16(sizeof(struct host_cmd_tlv_rts_threshold) -
-				    sizeof(struct host_cmd_tlv));
+				    sizeof(struct mwifiex_ie_types_header));
 		rts_threshold->rts_thr = cpu_to_le16(bss_cfg->rts_threshold);
 		cmd_size += sizeof(struct host_cmd_tlv_frag_threshold);
 		tlv += sizeof(struct host_cmd_tlv_frag_threshold);
@@ -528,21 +533,22 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
 	if ((bss_cfg->frag_threshold >= MWIFIEX_FRAG_MIN_VALUE) &&
 	    (bss_cfg->frag_threshold <= MWIFIEX_FRAG_MAX_VALUE)) {
 		frag_threshold = (struct host_cmd_tlv_frag_threshold *)tlv;
-		frag_threshold->tlv.type =
+		frag_threshold->header.type =
 				cpu_to_le16(TLV_TYPE_UAP_FRAG_THRESHOLD);
-		frag_threshold->tlv.len =
+		frag_threshold->header.len =
 			cpu_to_le16(sizeof(struct host_cmd_tlv_frag_threshold) -
-				    sizeof(struct host_cmd_tlv));
+				    sizeof(struct mwifiex_ie_types_header));
 		frag_threshold->frag_thr = cpu_to_le16(bss_cfg->frag_threshold);
 		cmd_size += sizeof(struct host_cmd_tlv_frag_threshold);
 		tlv += sizeof(struct host_cmd_tlv_frag_threshold);
 	}
 	if (bss_cfg->retry_limit <= MWIFIEX_RETRY_LIMIT) {
 		retry_limit = (struct host_cmd_tlv_retry_limit *)tlv;
-		retry_limit->tlv.type = cpu_to_le16(TLV_TYPE_UAP_RETRY_LIMIT);
-		retry_limit->tlv.len =
+		retry_limit->header.type =
+			cpu_to_le16(TLV_TYPE_UAP_RETRY_LIMIT);
+		retry_limit->header.len =
 			cpu_to_le16(sizeof(struct host_cmd_tlv_retry_limit) -
-				    sizeof(struct host_cmd_tlv));
+				    sizeof(struct mwifiex_ie_types_header));
 		retry_limit->limit = (u8)bss_cfg->retry_limit;
 		cmd_size += sizeof(struct host_cmd_tlv_retry_limit);
 		tlv += sizeof(struct host_cmd_tlv_retry_limit);
@@ -557,21 +563,21 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
 	if ((bss_cfg->auth_mode <= WLAN_AUTH_SHARED_KEY) ||
 	    (bss_cfg->auth_mode == MWIFIEX_AUTH_MODE_AUTO)) {
 		auth_type = (struct host_cmd_tlv_auth_type *)tlv;
-		auth_type->tlv.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE);
-		auth_type->tlv.len =
+		auth_type->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE);
+		auth_type->header.len =
 			cpu_to_le16(sizeof(struct host_cmd_tlv_auth_type) -
-			sizeof(struct host_cmd_tlv));
+			sizeof(struct mwifiex_ie_types_header));
 		auth_type->auth_type = (u8)bss_cfg->auth_mode;
 		cmd_size += sizeof(struct host_cmd_tlv_auth_type);
 		tlv += sizeof(struct host_cmd_tlv_auth_type);
 	}
 	if (bss_cfg->protocol) {
 		encrypt_protocol = (struct host_cmd_tlv_encrypt_protocol *)tlv;
-		encrypt_protocol->tlv.type =
+		encrypt_protocol->header.type =
 			cpu_to_le16(TLV_TYPE_UAP_ENCRY_PROTOCOL);
-		encrypt_protocol->tlv.len =
+		encrypt_protocol->header.len =
 			cpu_to_le16(sizeof(struct host_cmd_tlv_encrypt_protocol)
-			- sizeof(struct host_cmd_tlv));
+			- sizeof(struct mwifiex_ie_types_header));
 		encrypt_protocol->proto = cpu_to_le16(bss_cfg->protocol);
 		cmd_size += sizeof(struct host_cmd_tlv_encrypt_protocol);
 		tlv += sizeof(struct host_cmd_tlv_encrypt_protocol);
@@ -608,9 +614,9 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
 
 	if (bss_cfg->sta_ao_timer) {
 		ao_timer = (struct host_cmd_tlv_ageout_timer *)tlv;
-		ao_timer->tlv.type = cpu_to_le16(TLV_TYPE_UAP_AO_TIMER);
-		ao_timer->tlv.len = cpu_to_le16(sizeof(*ao_timer) -
-						sizeof(struct host_cmd_tlv));
+		ao_timer->header.type = cpu_to_le16(TLV_TYPE_UAP_AO_TIMER);
+		ao_timer->header.len = cpu_to_le16(sizeof(*ao_timer) -
+					sizeof(struct mwifiex_ie_types_header));
 		ao_timer->sta_ao_timer = cpu_to_le32(bss_cfg->sta_ao_timer);
 		cmd_size += sizeof(*ao_timer);
 		tlv += sizeof(*ao_timer);
@@ -618,9 +624,10 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
 
 	if (bss_cfg->ps_sta_ao_timer) {
 		ps_ao_timer = (struct host_cmd_tlv_ageout_timer *)tlv;
-		ps_ao_timer->tlv.type = cpu_to_le16(TLV_TYPE_UAP_PS_AO_TIMER);
-		ps_ao_timer->tlv.len = cpu_to_le16(sizeof(*ps_ao_timer) -
-						   sizeof(struct host_cmd_tlv));
+		ps_ao_timer->header.type =
+				cpu_to_le16(TLV_TYPE_UAP_PS_AO_TIMER);
+		ps_ao_timer->header.len = cpu_to_le16(sizeof(*ps_ao_timer) -
+				sizeof(struct mwifiex_ie_types_header));
 		ps_ao_timer->sta_ao_timer =
 					cpu_to_le32(bss_cfg->ps_sta_ao_timer);
 		cmd_size += sizeof(*ps_ao_timer);
@@ -636,16 +643,17 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
 static int mwifiex_uap_custom_ie_prepare(u8 *tlv, void *cmd_buf, u16 *ie_size)
 {
 	struct mwifiex_ie_list *ap_ie = cmd_buf;
-	struct host_cmd_tlv *tlv_ie = (struct host_cmd_tlv *)tlv;
+	struct mwifiex_ie_types_header *tlv_ie = (void *)tlv;
 
 	if (!ap_ie || !ap_ie->len || !ap_ie->ie_list)
 		return -1;
 
-	*ie_size += le16_to_cpu(ap_ie->len) + sizeof(struct host_cmd_tlv);
+	*ie_size += le16_to_cpu(ap_ie->len) +
+			sizeof(struct mwifiex_ie_types_header);
 
 	tlv_ie->type = cpu_to_le16(TLV_TYPE_MGMT_IE);
 	tlv_ie->len = ap_ie->len;
-	tlv += sizeof(struct host_cmd_tlv);
+	tlv += sizeof(struct mwifiex_ie_types_header);
 
 	memcpy(tlv, ap_ie->ie_list, le16_to_cpu(ap_ie->len));
 
-- 
1.8.2.3


^ permalink raw reply related

* [PATCH 13/21] mwifiex: move if_ops.cleanup_if() call
From: Bing Zhao @ 2013-07-23  2:17 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Amitkumar Karwar, Avinash Patil,
	Yogesh Ashok Powar, Nishant Sarmukadam, Frank Huang, Bing Zhao
In-Reply-To: <1374545878-15683-1-git-send-email-bzhao@marvell.com>

From: Amitkumar Karwar <akarwar@marvell.com>

As if_ops.init_if() is called in mwifiex_register(),
corresponding cleanup routine should be called in
mwifiex_unregister().

Currently it's there in mwifiex_adapter_cleanup(), hence
interface specific cleanup is not performed if driver
initialization is failed.

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/mwifiex/init.c | 3 ---
 drivers/net/wireless/mwifiex/main.c | 3 +++
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 8ff5d7b..2cda7ee 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -394,9 +394,6 @@ mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
 
 	dev_dbg(adapter->dev, "info: free scan table\n");
 
-	if (adapter->if_ops.cleanup_if)
-		adapter->if_ops.cleanup_if(adapter);
-
 	if (adapter->sleep_cfm)
 		dev_kfree_skb_any(adapter->sleep_cfm);
 }
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 8217368..e64c369 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -191,6 +191,9 @@ static int mwifiex_unregister(struct mwifiex_adapter *adapter)
 {
 	s32 i;
 
+	if (adapter->if_ops.cleanup_if)
+		adapter->if_ops.cleanup_if(adapter);
+
 	del_timer(&adapter->cmd_timer);
 
 	/* Free private structures */
-- 
1.8.2.3


^ permalink raw reply related

* [PATCH 17/21] mwifiex: correction in mwifiex_check_fw_status() return status
From: Bing Zhao @ 2013-07-23  2:17 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Amitkumar Karwar, Avinash Patil,
	Yogesh Ashok Powar, Nishant Sarmukadam, Frank Huang, Bing Zhao
In-Reply-To: <1374545878-15683-1-git-send-email-bzhao@marvell.com>

From: Amitkumar Karwar <akarwar@marvell.com>

For PCIe cards, when wrong firmware is downloaded, firmware is
failed to be ready in 10 seconds. We should return an error at
this point. But currently we are sending first command to firmware.
As expected firmware doesn't respond to this command and command
timeout occurs.

This patch fixes the problem by removing unnecessary 'ret'
variable modifications in "if (ret) {" block.
The block is just supposed to update "adapter->winner" flag.

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/mwifiex/pcie.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index 098153f..52da8ee 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -1954,12 +1954,10 @@ mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num)
 		else if (!winner_status) {
 			dev_err(adapter->dev, "PCI-E is the winner\n");
 			adapter->winner = 1;
-			ret = -1;
 		} else {
 			dev_err(adapter->dev,
 				"PCI-E is not the winner <%#x,%d>, exit dnld\n",
 				ret, adapter->winner);
-			ret = 0;
 		}
 	}
 
-- 
1.8.2.3


^ permalink raw reply related

* [PATCH 10/21] mwifiex: add PCIe shutdown handler to avoid system hang on reboot
From: Bing Zhao @ 2013-07-23  2:17 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Amitkumar Karwar, Avinash Patil,
	Yogesh Ashok Powar, Nishant Sarmukadam, Frank Huang, Bing Zhao
In-Reply-To: <1374545878-15683-1-git-send-email-bzhao@marvell.com>

From: Amitkumar Karwar <akarwar@marvell.com>

If reboot command is issued when device is in connected state,
system hangs while booting. This issue is fixed by doing cleanup
in shutdown handler.

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/mwifiex/pcie.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index 4a57eb4..dce6486 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -235,6 +235,14 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
 	kfree(card);
 }
 
+static void mwifiex_pcie_shutdown(struct pci_dev *pdev)
+{
+	user_rmmod = 1;
+	mwifiex_pcie_remove(pdev);
+
+	return;
+}
+
 static DEFINE_PCI_DEVICE_TABLE(mwifiex_ids) = {
 	{
 		PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P,
@@ -268,6 +276,7 @@ static struct pci_driver __refdata mwifiex_pcie = {
 		.pm = &mwifiex_pcie_pm_ops,
 	},
 #endif
+	.shutdown = mwifiex_pcie_shutdown,
 };
 
 /*
-- 
1.8.2.3


^ permalink raw reply related

* [PATCH 07/21] mwifiex: skip registering mgmt frame that has already registered
From: Bing Zhao @ 2013-07-23  2:17 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Amitkumar Karwar, Avinash Patil,
	Yogesh Ashok Powar, Nishant Sarmukadam, Frank Huang, Bing Zhao,
	Stone Piao
In-Reply-To: <1374545878-15683-1-git-send-email-bzhao@marvell.com>

From: Stone Piao <piaoyun@marvell.com>

Before sending command to firmware, we need to check the frame type.
We skip registering the mgmt frame that has already been registered.

Signed-off-by: Stone Piao <piaoyun@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/mwifiex/cfg80211.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index d824fee..dbdd3b2 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -240,16 +240,20 @@ mwifiex_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
 				     u16 frame_type, bool reg)
 {
 	struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
+	u32 mask;
 
 	if (reg)
-		priv->mgmt_frame_mask |= BIT(frame_type >> 4);
+		mask = priv->mgmt_frame_mask | BIT(frame_type >> 4);
 	else
-		priv->mgmt_frame_mask &= ~BIT(frame_type >> 4);
+		mask = priv->mgmt_frame_mask & ~BIT(frame_type >> 4);
 
-	mwifiex_send_cmd_async(priv, HostCmd_CMD_MGMT_FRAME_REG,
-			       HostCmd_ACT_GEN_SET, 0, &priv->mgmt_frame_mask);
-
-	wiphy_dbg(wiphy, "info: mgmt frame registered\n");
+	if (mask != priv->mgmt_frame_mask) {
+		priv->mgmt_frame_mask = mask;
+		mwifiex_send_cmd_async(priv, HostCmd_CMD_MGMT_FRAME_REG,
+				       HostCmd_ACT_GEN_SET, 0,
+				       &priv->mgmt_frame_mask);
+		wiphy_dbg(wiphy, "info: mgmt frame registered\n");
+	}
 }
 
 /*
-- 
1.8.2.3


^ permalink raw reply related

* [PATCH 21/21] mwifiex: modify mwifiex_ap_sta_limits to advertise support for P2P
From: Bing Zhao @ 2013-07-23  2:17 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Amitkumar Karwar, Avinash Patil,
	Yogesh Ashok Powar, Nishant Sarmukadam, Frank Huang, Bing Zhao
In-Reply-To: <1374545878-15683-1-git-send-email-bzhao@marvell.com>

From: Avinash Patil <patila@marvell.com>

We support maximum simultaneous 2 non-AP station interfaces and
they can assume role of Station/P2P client/P2P GO.
Advertise this support to cfg80211 so that concurrent P2P/STA
operation is possible.

Signed-off-by: Avinash Patil <patila@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/mwifiex/cfg80211.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index dbdd3b2..cc334d5 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -25,7 +25,9 @@ module_param(reg_alpha2, charp, 0);
 
 static const struct ieee80211_iface_limit mwifiex_ap_sta_limits[] = {
 	{
-		.max = 2, .types = BIT(NL80211_IFTYPE_STATION),
+		.max = 2, .types = BIT(NL80211_IFTYPE_STATION) |
+				   BIT(NL80211_IFTYPE_P2P_GO) |
+				   BIT(NL80211_IFTYPE_P2P_CLIENT),
 	},
 	{
 		.max = 1, .types = BIT(NL80211_IFTYPE_AP),
-- 
1.8.2.3


^ permalink raw reply related

* [PATCH 14/21] mwifiex: add unregister_dev handler for usb interface
From: Bing Zhao @ 2013-07-23  2:17 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Amitkumar Karwar, Avinash Patil,
	Yogesh Ashok Powar, Nishant Sarmukadam, Frank Huang, Bing Zhao
In-Reply-To: <1374545878-15683-1-git-send-email-bzhao@marvell.com>

From: Amitkumar Karwar <akarwar@marvell.com>

Clear the data pointer stored in USB interface structure in
this handler. This helps to return from mwifiex_usb_disconnect()
if driver deinitialization is already performed while handling
an error path for mwifiex_usb_probe().

USB8797 card gets enumerated twice. First enumeration is for
firmware download and second enumeration expects firmware
initialization. mwifiex_usb_probe() always takes care of
deinitialization for first enumeration after firmware download.

Also, this change matches our handling for SDIO and PCIe
interfaces.

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/mwifiex/usb.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
index f90fe21..fca98b5 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -786,6 +786,13 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
 	return 0;
 }
 
+static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
+{
+	struct usb_card_rec *card = (struct usb_card_rec *)adapter->card;
+
+	usb_set_intfdata(card->intf, NULL);
+}
+
 static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
 				    struct mwifiex_fw_image *fw)
 {
@@ -978,6 +985,7 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
 
 static struct mwifiex_if_ops usb_ops = {
 	.register_dev =		mwifiex_register_dev,
+	.unregister_dev =	mwifiex_unregister_dev,
 	.wakeup =		mwifiex_pm_wakeup_card,
 	.wakeup_complete =	mwifiex_pm_wakeup_card_complete,
 
-- 
1.8.2.3


^ permalink raw reply related

* [PATCH 15/21] mwifiex: reduce firmware poll retries
From: Bing Zhao @ 2013-07-23  2:17 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Amitkumar Karwar, Avinash Patil,
	Yogesh Ashok Powar, Nishant Sarmukadam, Frank Huang, Bing Zhao
In-Reply-To: <1374545878-15683-1-git-send-email-bzhao@marvell.com>

From: Amitkumar Karwar <akarwar@marvell.com>

After downloading the firmware, firmware status is checked by
reading a register. Polling interval is 100 msecs. Therefore 100
retries means the status is checked for 10 secs which is more than
sufficient for firmware to get ready.

This patch removes 1000 retries macro usage, because 100secs
time is not practical.

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/mwifiex/fw.h   | 3 ---
 drivers/net/wireless/mwifiex/init.c | 1 -
 2 files changed, 4 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 1b45aa5..99c2729 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -85,9 +85,6 @@ enum KEY_TYPE_ID {
 #define WAPI_KEY_LEN			50
 
 #define MAX_POLL_TRIES			100
-
-#define MAX_MULTI_INTERFACE_POLL_TRIES  1000
-
 #define MAX_FIRMWARE_POLL_TRIES			100
 
 #define FIRMWARE_READY_SDIO				0xfedc
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 2cda7ee..e021a58 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -691,7 +691,6 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter,
 		if (!adapter->winner) {
 			dev_notice(adapter->dev,
 				   "FW already running! Skip FW dnld\n");
-			poll_num = MAX_MULTI_INTERFACE_POLL_TRIES;
 			goto poll_fw;
 		}
 	}
-- 
1.8.2.3


^ permalink raw reply related

* [PATCH 18/21] mwifiex: handle driver initialization error paths
From: Bing Zhao @ 2013-07-23  2:17 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Amitkumar Karwar, Avinash Patil,
	Yogesh Ashok Powar, Nishant Sarmukadam, Frank Huang, Bing Zhao
In-Reply-To: <1374545878-15683-1-git-send-email-bzhao@marvell.com>

From: Amitkumar Karwar <akarwar@marvell.com>

mwifiex_fw_dpc() asynchronously takes care of firmware download
and initialization. Currently the error paths in mwifiex_fw_dpc()
are not handled. So if wrong firmware is downloaded, required
cleanup work is not performed. memory is leaked and workqueue
remains unterminated in this case.

mwifiex_terminate_workqueue() is moved to avoid forward
declaration.

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/mwifiex/main.c | 83 ++++++++++++++++++++++++-------------
 drivers/net/wireless/mwifiex/main.h |  1 +
 2 files changed, 56 insertions(+), 28 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index e64c369..5644c7f 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -390,6 +390,17 @@ static void mwifiex_free_adapter(struct mwifiex_adapter *adapter)
 }
 
 /*
+ * This function cancels all works in the queue and destroys
+ * the main workqueue.
+ */
+static void mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
+{
+	flush_workqueue(adapter->workqueue);
+	destroy_workqueue(adapter->workqueue);
+	adapter->workqueue = NULL;
+}
+
+/*
  * This function gets firmware and initializes it.
  *
  * The main initialization steps followed are -
@@ -398,7 +409,7 @@ static void mwifiex_free_adapter(struct mwifiex_adapter *adapter)
  */
 static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
 {
-	int ret;
+	int ret, i;
 	char fmt[64];
 	struct mwifiex_private *priv;
 	struct mwifiex_adapter *adapter = context;
@@ -407,7 +418,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
 	if (!firmware) {
 		dev_err(adapter->dev,
 			"Failed to get firmware %s\n", adapter->fw_name);
-		goto done;
+		goto err_dnld_fw;
 	}
 
 	memset(&fw, 0, sizeof(struct mwifiex_fw_image));
@@ -420,7 +431,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
 	else
 		ret = mwifiex_dnld_fw(adapter, &fw);
 	if (ret == -1)
-		goto done;
+		goto err_dnld_fw;
 
 	dev_notice(adapter->dev, "WLAN FW is active\n");
 
@@ -432,13 +443,15 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
 	}
 
 	/* enable host interrupt after fw dnld is successful */
-	if (adapter->if_ops.enable_int)
-		adapter->if_ops.enable_int(adapter);
+	if (adapter->if_ops.enable_int) {
+		if (adapter->if_ops.enable_int(adapter))
+			goto err_dnld_fw;
+	}
 
 	adapter->init_wait_q_woken = false;
 	ret = mwifiex_init_fw(adapter);
 	if (ret == -1) {
-		goto done;
+		goto err_init_fw;
 	} else if (!ret) {
 		adapter->hw_status = MWIFIEX_HW_STATUS_READY;
 		goto done;
@@ -447,12 +460,12 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
 	wait_event_interruptible(adapter->init_wait_q,
 				 adapter->init_wait_q_woken);
 	if (adapter->hw_status != MWIFIEX_HW_STATUS_READY)
-		goto done;
+		goto err_init_fw;
 
 	priv = adapter->priv[MWIFIEX_BSS_ROLE_STA];
 	if (mwifiex_register_cfg80211(adapter)) {
 		dev_err(adapter->dev, "cannot register with cfg80211\n");
-		goto err_init_fw;
+		goto err_register_cfg80211;
 	}
 
 	rtnl_lock();
@@ -483,13 +496,39 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
 	goto done;
 
 err_add_intf:
-	mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev);
+	for (i = 0; i < adapter->priv_num; i++) {
+		priv = adapter->priv[i];
+
+		if (!priv)
+			continue;
+
+		if (priv->wdev && priv->netdev)
+			mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev);
+	}
 	rtnl_unlock();
+err_register_cfg80211:
+	wiphy_unregister(adapter->wiphy);
+	wiphy_free(adapter->wiphy);
 err_init_fw:
 	if (adapter->if_ops.disable_int)
 		adapter->if_ops.disable_int(adapter);
+err_dnld_fw:
 	pr_debug("info: %s: unregister device\n", __func__);
-	adapter->if_ops.unregister_dev(adapter);
+	if (adapter->if_ops.unregister_dev)
+		adapter->if_ops.unregister_dev(adapter);
+
+	if ((adapter->hw_status == MWIFIEX_HW_STATUS_FW_READY) ||
+	    (adapter->hw_status == MWIFIEX_HW_STATUS_READY)) {
+		pr_debug("info: %s: shutdown mwifiex\n", __func__);
+		adapter->init_wait_q_woken = false;
+
+		if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS)
+			wait_event_interruptible(adapter->init_wait_q,
+						 adapter->init_wait_q_woken);
+	}
+	adapter->surprise_removed = true;
+	mwifiex_terminate_workqueue(adapter);
+	mwifiex_free_adapter(adapter);
 done:
 	if (adapter->cal_data) {
 		release_firmware(adapter->cal_data);
@@ -497,6 +536,7 @@ done:
 	}
 	release_firmware(adapter->firmware);
 	complete(&adapter->fw_load);
+	up(adapter->card_sem);
 	return;
 }
 
@@ -807,18 +847,6 @@ static void mwifiex_main_work_queue(struct work_struct *work)
 }
 
 /*
- * This function cancels all works in the queue and destroys
- * the main workqueue.
- */
-static void
-mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
-{
-	flush_workqueue(adapter->workqueue);
-	destroy_workqueue(adapter->workqueue);
-	adapter->workqueue = NULL;
-}
-
-/*
  * This function adds the card.
  *
  * This function follows the following major steps to set up the device -
@@ -846,6 +874,7 @@ mwifiex_add_card(void *card, struct semaphore *sem,
 	}
 
 	adapter->iface_type = iface_type;
+	adapter->card_sem = sem;
 
 	adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;
 	adapter->surprise_removed = false;
@@ -876,17 +905,12 @@ mwifiex_add_card(void *card, struct semaphore *sem,
 		goto err_init_fw;
 	}
 
-	up(sem);
 	return 0;
 
 err_init_fw:
 	pr_debug("info: %s: unregister device\n", __func__);
 	if (adapter->if_ops.unregister_dev)
 		adapter->if_ops.unregister_dev(adapter);
-err_registerdev:
-	adapter->surprise_removed = true;
-	mwifiex_terminate_workqueue(adapter);
-err_kmalloc:
 	if ((adapter->hw_status == MWIFIEX_HW_STATUS_FW_READY) ||
 	    (adapter->hw_status == MWIFIEX_HW_STATUS_READY)) {
 		pr_debug("info: %s: shutdown mwifiex\n", __func__);
@@ -896,7 +920,10 @@ err_kmalloc:
 			wait_event_interruptible(adapter->init_wait_q,
 						 adapter->init_wait_q_woken);
 	}
-
+err_registerdev:
+	adapter->surprise_removed = true;
+	mwifiex_terminate_workqueue(adapter);
+err_kmalloc:
 	mwifiex_free_adapter(adapter);
 
 err_init_sw:
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index bb28d3d..9ee3b1b 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -749,6 +749,7 @@ struct mwifiex_adapter {
 
 	atomic_t is_tx_received;
 	atomic_t pending_bridged_pkts;
+	struct semaphore *card_sem;
 };
 
 int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);
-- 
1.8.2.3


^ permalink raw reply related

* [PATCH 11/21] mwifiex: move del_timer_sync(scan_delay_timer) call to fix memleak
From: Bing Zhao @ 2013-07-23  2:17 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Amitkumar Karwar, Avinash Patil,
	Yogesh Ashok Powar, Nishant Sarmukadam, Frank Huang, Bing Zhao
In-Reply-To: <1374545878-15683-1-git-send-email-bzhao@marvell.com>

From: Amitkumar Karwar <akarwar@marvell.com>

Currently it is in mwifiex_adapter_cleanup() which doesn't get
called if driver initialization is failed causing memory leak.

scan_delay_timer is initialized in mwifiex_register(), so it
should be deleted in mwifiex_unregister(). Hence it has been
moved to appropriate place.

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/mwifiex/init.c | 7 -------
 drivers/net/wireless/mwifiex/main.c | 1 +
 2 files changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 09c4b76..787cff8 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -378,18 +378,11 @@ static void mwifiex_free_lock_list(struct mwifiex_adapter *adapter)
 static void
 mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
 {
-	int i;
-
 	if (!adapter) {
 		pr_err("%s: adapter is NULL\n", __func__);
 		return;
 	}
 
-	for (i = 0; i < adapter->priv_num; i++) {
-		if (adapter->priv[i])
-			del_timer_sync(&adapter->priv[i]->scan_delay_timer);
-	}
-
 	mwifiex_cancel_all_pending_cmd(adapter);
 
 	/* Free lock variables */
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 1753431..8217368 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -197,6 +197,7 @@ static int mwifiex_unregister(struct mwifiex_adapter *adapter)
 	for (i = 0; i < adapter->priv_num; i++) {
 		if (adapter->priv[i]) {
 			mwifiex_free_curr_bcn(adapter->priv[i]);
+			del_timer_sync(&adapter->priv[i]->scan_delay_timer);
 			kfree(adapter->priv[i]);
 		}
 	}
-- 
1.8.2.3


^ permalink raw reply related


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