Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: [PATCH RFC] mac80211: Extend channel to frequency mapping for 802.11j
From: Dave Kilroy @ 2010-12-29 13:55 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Bruno Randolf, linville, linux-wireless
In-Reply-To: <1293529983.3526.9.camel@jlt3.sipsolutions.net>

On Tue, Dec 28, 2010 at 9:53 AM, Johannes Berg
<johannes@sipsolutions.net> wrote:
> On Tue, 2010-12-28 at 10:51 +0100, Johannes Berg wrote:
>
>> > ieee80211_dsss_chan_to_freq - atmel, airo, wl3501_cs, orinoco, rndis_wlan
>> > ieee80211_freq_to_dsss_chan - atmel, airo, orinoco, zd1201
>> >
>> > Anyhow i guess it would make sense to have a common channel to frequency
>> > mapping function for mac80211 and other wireless drivers? The problem is now
>> > we have to use enum ieee80211_band which is defined cfg80211.h...
>
> Interestingly, I just noticed that the above ones also have different
> semantics -- they try to round to the nearest channel rather than
> returning an error if the center frequency isn't exact.

I suspect I introduced these functions while refactoring orinoco (well
before the cfg80211 conversion). If I recall correctly, there was no
specific reason for the round to nearest behaviour - it just seemed
more appropriate than rounding down the frequencies. So if it helps, I
don't see why we shouldn't modify the behaviour of the ieee80211
functions where necessary.

Dave.

^ permalink raw reply

* Re: BUG: Microcode SW error detected / Frequent disconnects
From: Florian Kriener @ 2010-12-29 11:01 UTC (permalink / raw)
  To: Guy, Wey-Yi; +Cc: sedat.dilek@gmail.com, linux-wireless@vger.kernel.org
In-Reply-To: <201012102010.16921.florian@kriener.org>

On Friday 10 December 2010 20:10:16 Florian Kriener wrote:
> On Friday 10 December 2010 16:26:14 Guy, Wey-Yi wrote:
> > Looks like you have 5000 NIC device based on the firmware version.
> > Please let me know the problem still happen in 2.6.36. If does, we
> > can look into possible firmware problem
> 
> Yes, it is a 5300 . I guess you mean 2.6.37 and yes I will let you
> know.

I promised to mail again if I see the firmware error again with 2.6.37.
There you go:


[ 2296.117090] iwlagn 0000:03:00.0: Aggregation not enabled for tid 0 because load = 4
[ 2298.344144] iwlagn 0000:03:00.0: iwlagn_tx_agg_start on ra = 00:1f:3f:62:fd:83 tid = 0
[ 3132.669181] iwlagn 0000:03:00.0: low ack count detected, restart firmware
[ 3132.669190] iwlagn 0000:03:00.0: On demand firmware reload
[ 3132.706279] iwlagn 0000:03:00.0: Stopping AGG while state not ON or starting
[ 3132.706290] iwlagn 0000:03:00.0: queue number out of range: 0, must be 10 to 19
[ 3209.576047] iwlagn 0000:03:00.0: iwlagn_tx_agg_start on ra = 00:1f:3f:62:fd:83 tid = 0
[ 4913.689836] iwlagn 0000:03:00.0: Microcode SW error detected.  Restarting 0x2000000.
[ 4913.689846] iwlagn 0000:03:00.0: Loaded firmware version: 8.24.2.12
[ 4913.689866] iwlagn 0000:03:00.0: Start IWL Error Log Dump:
[ 4913.689873] iwlagn 0000:03:00.0: Status: 0x000212E4, count: 5
[ 4913.690031] iwlagn 0000:03:00.0: Desc                                  Time       data1      data2      line
[ 4913.690041] iwlagn 0000:03:00.0: SYSASSERT                    (0x0005) 0000521857 0x00008035 0x00006905 1364
[ 4913.690047] iwlagn 0000:03:00.0: pc      blink1  blink2  ilink1  ilink2  hcmd
[ 4913.690055] iwlagn 0000:03:00.0: 0x03AE8 0x039B8 0x039B8 0x008B2 0x00000 0x4E7004E
[ 4913.690060] iwlagn 0000:03:00.0: CSR values:
[ 4913.690065] iwlagn 0000:03:00.0: (2nd byte of CSR_INT_COALESCING is CSR_INT_PERIODIC_REG)
[ 4913.690075] iwlagn 0000:03:00.0:        CSR_HW_IF_CONFIG_REG: 0X00480302
[ 4913.690084] iwlagn 0000:03:00.0:          CSR_INT_COALESCING: 0X0000ff40
[ 4913.690093] iwlagn 0000:03:00.0:                     CSR_INT: 0X00000000
[ 4913.690101] iwlagn 0000:03:00.0:                CSR_INT_MASK: 0X00000000
[ 4913.690110] iwlagn 0000:03:00.0:           CSR_FH_INT_STATUS: 0X00000000
[ 4913.690118] iwlagn 0000:03:00.0:                 CSR_GPIO_IN: 0X00000000
[ 4913.690127] iwlagn 0000:03:00.0:                   CSR_RESET: 0X00000000
[ 4913.690135] iwlagn 0000:03:00.0:                CSR_GP_CNTRL: 0X080403c5
[ 4913.690143] iwlagn 0000:03:00.0:                  CSR_HW_REV: 0X00000024
[ 4913.690152] iwlagn 0000:03:00.0:              CSR_EEPROM_REG: 0X00000000
[ 4913.690160] iwlagn 0000:03:00.0:               CSR_EEPROM_GP: 0X90000004
[ 4913.690169] iwlagn 0000:03:00.0:              CSR_OTP_GP_REG: 0X00060000
[ 4913.690178] iwlagn 0000:03:00.0:                 CSR_GIO_REG: 0X00080046
[ 4913.690186] iwlagn 0000:03:00.0:            CSR_GP_UCODE_REG: 0X00000885
[ 4913.690195] iwlagn 0000:03:00.0:           CSR_GP_DRIVER_REG: 0X00000000
[ 4913.690203] iwlagn 0000:03:00.0:           CSR_UCODE_DRV_GP1: 0X00000000
[ 4913.690211] iwlagn 0000:03:00.0:           CSR_UCODE_DRV_GP2: 0X00000000
[ 4913.690220] iwlagn 0000:03:00.0:                 CSR_LED_REG: 0X00000058
[ 4913.690229] iwlagn 0000:03:00.0:        CSR_DRAM_INT_TBL_REG: 0X88134338
[ 4913.690237] iwlagn 0000:03:00.0:        CSR_GIO_CHICKEN_BITS: 0X27800200
[ 4913.690246] iwlagn 0000:03:00.0:             CSR_ANA_PLL_CFG: 0X00880300
[ 4913.690255] iwlagn 0000:03:00.0:           CSR_HW_REV_WA_REG: 0X0001001a
[ 4913.690263] iwlagn 0000:03:00.0:        CSR_DBG_HPET_MEM_REG: 0Xffff0000
[ 4913.690269] iwlagn 0000:03:00.0: FH register values:
[ 4913.690287] iwlagn 0000:03:00.0:         FH_RSCSR_CHNL0_STTS_WPTR_REG: 0X13623e00
[ 4913.690305] iwlagn 0000:03:00.0:        FH_RSCSR_CHNL0_RBDCB_BASE_REG: 0X01367fb0
[ 4913.690324] iwlagn 0000:03:00.0:                  FH_RSCSR_CHNL0_WPTR: 0X00000050
[ 4913.690342] iwlagn 0000:03:00.0:         FH_MEM_RCSR_CHNL0_CONFIG_REG: 0X80819104
[ 4913.690361] iwlagn 0000:03:00.0:          FH_MEM_RSSR_SHARED_CTRL_REG: 0X000000fc
[ 4913.690380] iwlagn 0000:03:00.0:            FH_MEM_RSSR_RX_STATUS_REG: 0X07030000
[ 4913.690398] iwlagn 0000:03:00.0:    FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV: 0X00000000
[ 4913.690416] iwlagn 0000:03:00.0:                FH_TSSR_TX_STATUS_REG: 0X07ff0001
[ 4913.690435] iwlagn 0000:03:00.0:                 FH_TSSR_TX_ERROR_REG: 0X00000000
[ 4913.690497] iwlagn 0000:03:00.0: Start IWL Event Log Dump: display last 20 entries
[ 4913.690522] iwlagn 0000:03:00.0: EVT_LOGT:1780995800:0x00000000:0212
[ 4913.690537] iwlagn 0000:03:00.0: EVT_LOGT:1780995854:0x00000000:0215
[ 4913.690553] iwlagn 0000:03:00.0: EVT_LOGT:1780995858:0x00000008:0220
[ 4913.690568] iwlagn 0000:03:00.0: EVT_LOGT:1780996115:0x0a1a001c:0206
[ 4913.690584] iwlagn 0000:03:00.0: EVT_LOGT:1780996117:0xc0000000:0228
[ 4913.690600] iwlagn 0000:03:00.0: EVT_LOGT:1780996118:0x00000001:0204
[ 4913.690615] iwlagn 0000:03:00.0: EVT_LOGT:1780996121:0x00000001:0214
[ 4913.690630] iwlagn 0000:03:00.0: EVT_LOGT:1780996122:0x01041110:0205
[ 4913.690646] iwlagn 0000:03:00.0: EVT_LOGT:1780996144:0x00000020:0208
[ 4913.690661] iwlagn 0000:03:00.0: EVT_LOGT:1780996163:0x00000000:0302
[ 4913.690677] iwlagn 0000:03:00.0: EVT_LOGT:1780996193:0x000000c4:0303
[ 4913.690693] iwlagn 0000:03:00.0: EVT_LOGT:1780996199:0x00000001:0203
[ 4913.690708] iwlagn 0000:03:00.0: EVT_LOGT:1780996203:0x0a1a001c:0206
[ 4913.690723] iwlagn 0000:03:00.0: EVT_LOGT:1780996204:0x00000040:0204
[ 4913.690739] iwlagn 0000:03:00.0: EVT_LOGT:1780996207:0x01040110:0211
[ 4913.690754] iwlagn 0000:03:00.0: EVT_LOGT:1780996212:0x00000000:0212
[ 4913.690769] iwlagn 0000:03:00.0: EVT_LOGT:1780996266:0x00000000:0215
[ 4913.690785] iwlagn 0000:03:00.0: EVT_LOGT:1780996270:0x00000008:0220
[ 4913.690800] iwlagn 0000:03:00.0: EVT_LOGT:1780996636:0x04e7004e:0401
[ 4913.690816] iwlagn 0000:03:00.0: EVT_LOGT:1780996648:0x00000000:0125
[ 4913.736574] iwlagn 0000:03:00.0: Stopping AGG while state not ON or starting
[ 4913.736584] iwlagn 0000:03:00.0: queue number out of range: 0, must be 10 to 19
[ 4964.632025] iwlagn 0000:03:00.0: Aggregation not enabled for tid 0 because load = 0
[ 4973.649242] iwlagn 0000:03:00.0: iwlagn_tx_agg_start on ra = 00:1f:3f:62:fd:83 tid = 0
[ 5037.471815] iwlagn 0000:03:00.0: low ack count detected, restart firmware
[ 5037.471824] iwlagn 0000:03:00.0: On demand firmware reload
[ 5037.507502] iwlagn 0000:03:00.0: Stopping AGG while state not ON or starting
[ 5037.507513] iwlagn 0000:03:00.0: queue number out of range: 0, must be 10 to 19


The card is a iwl5300 and the kernel is of version 2.6.37-rc7 running on amd64 arch.
It's the newest from debian experimental (2.6.37~rc7-1~experimental.1).

I have a full dmesg.log here which I can send you in private, just ask.

Sincerely,
Florian.

^ permalink raw reply

* Re: [PATCH v3 14/18] wl1271: AP mode - record TX configuration settings
From: Luciano Coelho @ 2010-12-29  9:21 UTC (permalink / raw)
  To: ext Arik Nemtsov; +Cc: linux-wireless
In-Reply-To: <1293557808-27068-15-git-send-email-arik@wizery.com>

On Tue, 2010-12-28 at 19:36 +0200, ext Arik Nemtsov wrote:
> 
> diff --git a/drivers/net/wireless/wl12xx/main.c
> b/drivers/net/wireless/wl12xx/main.c
> index 3747d98..ea61ae7 100644
> --- a/drivers/net/wireless/wl12xx/main.c
> +++ b/drivers/net/wireless/wl12xx/main.c
> @@ -1433,6 +1433,8 @@ static int wl1271_op_config(struct ieee80211_hw
> *hw, u32 changed)
>                 goto out;
>         }
>  
> +       is_ap = (wl->bss_type == BSS_TYPE_AP_BSS);
> +
>         ret = wl1271_ps_elp_wakeup(wl, false);
>         if (ret < 0)
>                 goto out; 

Did you forget to fix this one? As we discussed, this should be in
10/18.


-- 
Cheers,
Luca.


^ permalink raw reply

* Re: [PATCH 4/4] mwl8k: Enable HW encryption for AP mode
From: Johannes Berg @ 2010-12-29  9:18 UTC (permalink / raw)
  To: Thomas Pedersen
  Cc: linux-wireless, mwl8k-devel, buytenh, Nishant Sarmukadam,
	Pradeep Nemavat
In-Reply-To: <1293614230.3546.4.camel@jlt3.sipsolutions.net>

On Wed, 2010-12-29 at 10:17 +0100, Johannes Berg wrote:
> On Tue, 2010-12-28 at 15:01 -0800, Thomas Pedersen wrote:
> 
> > @@ -824,15 +827,22 @@ static void mwl8k_encapsulate_tx_frame(struct sk_buff *skb)
> >  	header_pad = 0;
> >  	data_pad = 0;
> >  	if (key_conf != NULL) {
> > -		if (key_conf->alg == ALG_WEP) {
> > +		switch (key_conf->cipher) {
> 
> how can this patch possibly apply? key_conf->alg hasn't existed in a
> LONG time, so I don't see how you can be removing a line containing it?!

Oh, never mind, patch 2/4 is adding this code, so it can never
compile...........

johannes


^ permalink raw reply

* Re: [PATCH 4/4] mwl8k: Enable HW encryption for AP mode
From: Johannes Berg @ 2010-12-29  9:17 UTC (permalink / raw)
  To: Thomas Pedersen
  Cc: linux-wireless, mwl8k-devel, buytenh, Nishant Sarmukadam,
	Pradeep Nemavat
In-Reply-To: <1293577297-25755-5-git-send-email-thomas@cozybit.com>

On Tue, 2010-12-28 at 15:01 -0800, Thomas Pedersen wrote:

> @@ -824,15 +827,22 @@ static void mwl8k_encapsulate_tx_frame(struct sk_buff *skb)
>  	header_pad = 0;
>  	data_pad = 0;
>  	if (key_conf != NULL) {
> -		if (key_conf->alg == ALG_WEP) {
> +		switch (key_conf->cipher) {

how can this patch possibly apply? key_conf->alg hasn't existed in a
LONG time, so I don't see how you can be removing a line containing it?!

johannes


^ permalink raw reply

* Re: [PATCH 3/4] mwl8k: Set mac80211 rx status flags appropriately when hw crypto is enabled
From: Johannes Berg @ 2010-12-29  9:15 UTC (permalink / raw)
  To: Thomas Pedersen
  Cc: linux-wireless, mwl8k-devel, buytenh, Nishant Sarmukadam,
	yogesh powar
In-Reply-To: <1293577297-25755-4-git-send-email-thomas@cozybit.com>

On Tue, 2010-12-28 at 15:01 -0800, Thomas Pedersen wrote:
> From: Nishant Sarmukadam <nishants@marvell.com>
> 
> When hw crypto is enabled, set rx status flags appropriately depending on
> whether hw crypto is enabled for a particular bss.
> Also report MIC errors to mac80211, so that counter measures can be
> initiated

> +	if ((rxd->rx_status != MWL8K_8366_AP_RXSTAT_GENERAL_DECRYPT_ERR) &&
> +		(rxd->rx_status & MWL8K_8366_AP_RXSTAT_DECRYPT_ERR_MASK) &&
> +		(rxd->rx_status & MWL8K_8366_AP_RXSTAT_TKIP_DECRYPT_MIC_ERR))
> +			status->flag |= RX_FLAG_MMIC_ERROR;

It's not my driver, so I don't care a whole lot, but this patch has some
pretty messed up indentation.

johannes


^ permalink raw reply

* Re: [PATCH 2/4] mwl8k: Add encapsulation of data packet for crypto
From: Johannes Berg @ 2010-12-29  9:14 UTC (permalink / raw)
  To: Thomas Pedersen
  Cc: linux-wireless, mwl8k-devel, buytenh, Nishant Sarmukadam,
	Pradeep Nemavat
In-Reply-To: <1293577297-25755-3-git-send-email-thomas@cozybit.com>

On Tue, 2010-12-28 at 15:01 -0800, Thomas Pedersen wrote:

> Different head and tail pads will be needed for crypto depending on
> the crypto mode. Add support to encapsulate the packets with
> appropriate pad values. Also, fill the header in case of CCMP.

Err, mac80211 is perfectly capable of generating the CCMP header, you
should use that functionality (and maybe memmove it elsewhere if needed)

johannes


^ permalink raw reply

* Re: cfg80211 warnings
From: Johannes Berg @ 2010-12-29  8:55 UTC (permalink / raw)
  To: Vipin Mehta; +Cc: lrodriguez, linux-wireless@vger.kernel.org
In-Reply-To: <20101229021535.GA17397@vmehta-desktop>

On Tue, 2010-12-28 at 18:15 -0800, Vipin Mehta wrote:

>      I was testing a cfg80211 driver when I encountered the following
> warning in the function core.c:wdev_cleanup_work().
> 
>         if (WARN_ON(rdev->scan_req && rdev->scan_req->dev ==
> wdev->netdev)) {
>                 rdev->scan_req->aborted = true;
>                 ___cfg80211_scan_done(rdev, true);
>         }
> 
> Soon enough it leads to another warning in the function
> scan.c:cfg80211_scan_done() when the pending scan operation completes.
>         WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req);
> 
> The sequence of operation is:
> 1) Connect to an open access point.
> 2) Disconnect.
> 3) Scan via a call to nl80211_trigger_scan.
> 4) A call to cfg80211_netdev_notifier_call() with the state
> NETDEV_GOING_DOWN while the previous scan operation is pending.
> 5) A call to cfg80211_netdev_notifier_call() with the state
> NETDEV_DOWN while the previous scan operation is pending.
> 
> The first warning is observed after step 5) because of a pending scan
> request. The second warning is seen when the driver returns the scan
> results once the pending scan operation is completed. This is because
> cfg80211 had already freed up the pending scan request in the context
> of NETDEV_DOWN.
> 
> Unfortunately, I dont see a way for the cfg80211 driver to get
> notified when the interface is going down since the driver could have
> aborted the pending scan in that case.
> 
> Is the above sequence of operations valid and is cfg80211 expected to
> handle it without the warnings? Is the driver missing some hooks?

The driver is expected to abort scans when interfaces go down, and it
can know that from the mac80211 stop() callback, or the netdev's
ndo_stop() callback (for pure cfg80211 drivers).

johannes


^ permalink raw reply

* Re: [linux-pm] subtle pm_runtime_put_sync race and sdio functions
From: Ohad Ben-Cohen @ 2010-12-29  8:01 UTC (permalink / raw)
  To: Alan Stern
  Cc: Rafael J. Wysocki, linux-pm, Johannes Berg, linux-wireless,
	linux-mmc, Ido Yariv, Kevin Hilman
In-Reply-To: <Pine.LNX.4.44L0.1012281541580.22998-100000@netrider.rowland.org>

On Tue, Dec 28, 2010 at 11:46 PM, Alan Stern <stern@rowland.harvard.edu> wrote:
> Similarly, during system suspend mmc_suspend_host() should be
> responsible for doing all the necessary power-down operations.  Runtime
> PM is completely out of the picture at this time.  And this should be
> independent of mac80211 -- in fact, the card should be powered down
> appropriately even if the kernel doesn't have a mac80211 layer.

And it is.

But in order to boot the firmware on resume, we need to reset the
device. And if system suspend has been cancelled before
mmc_power_off() was invoked, we will not be able to. So, in this case
too, the driver will have to power the device off.

It all really boils down to the same solution - we will always have to
bypass runtime PM and directly control the power of the device.

^ permalink raw reply

* Re: [linux-pm] subtle pm_runtime_put_sync race and sdio functions
From: Ohad Ben-Cohen @ 2010-12-29  6:34 UTC (permalink / raw)
  To: Alan Stern
  Cc: Rafael J. Wysocki, linux-pm, Johannes Berg, linux-wireless,
	linux-mmc, Ido Yariv, Kevin Hilman
In-Reply-To: <Pine.LNX.4.44L0.1012281541580.22998-100000@netrider.rowland.org>

On Tue, Dec 28, 2010 at 11:46 PM, Alan Stern <stern@rowland.harvard.edu> wrote:
> What's the relation between mmc_power_off() and mmc_power_save_host()?

Essentially they are the same - mmc_power_off() is the one that
actually powers off the card.

mmc_power_save_host() just invokes first a bus-specific ->power_save()
handler (if one exists).

> Does one merely go into a low-power state whereas the other does the
> complete-power-off reset?

No, think of them as the same. Both will lead to a complete power off.
The mmc_power_off() is just an internal function which belongs to the
MMC core.

> During wlan-interface-down, it's not necessary to reduce the power
> level; it's merely desirable.  That's exactly the sort of thing runtime
> PM is meant for.  Hence the existing call to pm_runtime_put_sync() is
> sufficient.

Not exactly - think of airplane mode, where we must ensure the radios
are disabled, without being blocked by /sys/devices/.../power/control
- we will need to bypass runtime PM in this scenario too.

> Put it another way:  Suppose an SDIO card has more than one function
> and you need to reset the wl1271 function.  It sounds like there's no
> way to do this without resetting the other functions as well.  What
> happens if another function's driver is busy and can't allow a reset
> just then?

That's a chip specific thing. In our case, there is no other active
SDIO function.

Other vendors which does employ several SDIO functions have a separate
reset for each function _in addition_ to the power line. So for them
the runtime PM model is just great - they never care if the actual
power is down or not - it's really just about power consumption, and
nothing else. When they need an unconditional reset, they just use the
appropriate reset line.

In our case we have a single control for both power and reset
functionality (actually we do have a separate power line to the
device, but it is not controlled by software - it is fed directly from
the battery rail).

^ permalink raw reply

* Re: Compile error for the last week inside rtlwifi/base.c
From: Larry Finger @ 2010-12-29  3:44 UTC (permalink / raw)
  To: Weedy; +Cc: linux-wireless
In-Reply-To: <loom.20101229T034155-409@post.gmane.org>

On 12/28/2010 08:43 PM, Weedy wrote:
> Larry Finger <Larry.Finger@...> writes:
> 
>> Older kernels used create_workqueue(), which is replaced by alloc_workqueue()
>> If you really need the driver for RTL8192CE/RTL8188CE, then apply the patch
>> shown below. If you do not need the driver, then disable it in the 
>> configuration.
>>
>> Larry
> 
> Actually I need RTL8192USB, I guess I need to wait more?

Yes. The rtlwifi driver is for PCIe devices.

^ permalink raw reply

* Re: Compile error for the last week inside rtlwifi/base.c
From: Weedy @ 2010-12-29  2:43 UTC (permalink / raw)
  To: linux-wireless
In-Reply-To: <4D1A0EF1.8060509@lwfinger.net>

Larry Finger <Larry.Finger@...> writes:

> Older kernels used create_workqueue(), which is replaced by alloc_workqueue()
> If you really need the driver for RTL8192CE/RTL8188CE, then apply the patch
> shown below. If you do not need the driver, then disable it in the 
> configuration.
> 
> Larry

Actually I need RTL8192USB, I guess I need to wait more?


^ permalink raw reply

* [PATCH 2/2] mwifiex: remove redundant event handling
From: Bing Zhao @ 2010-12-29  1:59 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Johannes Berg, Amitkumar Karwar, Kiran Divekar,
	Frank Huang, Bing Zhao
In-Reply-To: <1293587963-26616-1-git-send-email-bzhao@marvell.com>

From: Kiran Divekar <dkiran@marvell.com>

The events should be handled directly. The extra handling of
passing them to higher layer is redundant.

Signed-off-by: Kiran Divekar <dkiran@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/mwifiex/cmdevt.c      |   46 +--------
 drivers/net/wireless/mwifiex/decl.h        |   44 ---------
 drivers/net/wireless/mwifiex/join.c        |   30 ++----
 drivers/net/wireless/mwifiex/main.c        |    1 -
 drivers/net/wireless/mwifiex/main.h        |    8 --
 drivers/net/wireless/mwifiex/scan.c        |    9 ++-
 drivers/net/wireless/mwifiex/sta_cmdresp.c |    9 +-
 drivers/net/wireless/mwifiex/sta_event.c   |  121 +++++-------------------
 drivers/net/wireless/mwifiex/sta_ioctl.c   |    2 -
 drivers/net/wireless/mwifiex/util.c        |  142 +---------------------------
 drivers/net/wireless/mwifiex/wmm.c         |    2 -
 11 files changed, 53 insertions(+), 361 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 1f70cef..dee8550 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -403,40 +403,6 @@ done:
 }
 
 /*
- * This function handles events generated by driver.
- *
- * The caller can provide with either the complete event structure,
- * or just an event ID, in which case a blank event will be created
- * by the function automatically. If both are provided, the event body
- * is used and the id is ignored.
- */
-enum mwifiex_status
-mwifiex_recv_event(struct mwifiex_private *priv,
-			enum mwifiex_event_id event_id,
-			struct mwifiex_event *event)
-{
-
-	ENTER();
-
-	if (event) {
-		/* The caller has provided the event. */
-		mwifiex_process_recv_event(priv->adapter, event);
-	} else {
-		struct mwifiex_event mevent;
-
-		memset(&mevent, 0, sizeof(struct mwifiex_event));
-		mevent.bss_index = priv->bss_index;
-		mevent.event_id = event_id;
-		mevent.event_len = 0;
-
-		mwifiex_process_recv_event(priv->adapter, &mevent);
-	}
-
-	LEAVE();
-	return MWIFIEX_STATUS_SUCCESS;
-}
-
-/*
  * This function allocates the command buffers and links them to
  * the command free queue.
  *
@@ -1287,16 +1253,14 @@ mwifiex_hs_activated_event(struct mwifiex_private *priv, u8 activated)
 		if (priv->adapter->is_hs_configured) {
 			priv->adapter->hs_activated = true;
 			PRINTM(MEVENT, "hs_actived\n");
-			mwifiex_recv_event(priv,
-					   MWIFIEX_EVENT_ID_DRV_HS_ACTIVATED,
-					   NULL);
+			priv->adapter->hs_activate_wait_q_woken = true;
+			wake_up_interruptible(
+				&priv->adapter->hs_activate_wait_q);
 		} else
 			PRINTM(MWARN, "hs_activated: HS not configured !!!\n");
 	} else {
 		PRINTM(MEVENT, "hs_deactived\n");
 		priv->adapter->hs_activated = false;
-		mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_DRV_HS_DEACTIVATED,
-				   NULL);
 	}
 
 	LEAVE();
@@ -1313,11 +1277,11 @@ mwifiex_host_sleep_wakeup_event(struct mwifiex_private *priv)
 	ENTER();
 
 	if (priv->adapter->is_hs_configured)
-		mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_FW_HS_WAKEUP, NULL);
+		/* simulate HSCFG_CANCEL command */
+		mwifiex_cancel_hs(priv, MWIFIEX_NO_WAIT);
 	else
 		PRINTM(MWARN, "hs_wakeup: Host Sleep not configured !!!\n");
 
-
 	LEAVE();
 }
 
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index 95d9642..30d66c0 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -117,43 +117,6 @@ enum mwifiex_data_frame_type {
 	MWIFIEX_DATA_FRAME_TYPE_802_11,
 };
 
-enum mwifiex_event_id {
-	MWIFIEX_EVENT_ID_FW_UNKNOWN = 0x00000001,
-	MWIFIEX_EVENT_ID_FW_ADHOC_LINK_SENSED,
-	MWIFIEX_EVENT_ID_FW_ADHOC_LINK_LOST,
-	MWIFIEX_EVENT_ID_FW_DISCONNECTED,
-	MWIFIEX_EVENT_ID_FW_MIC_ERR_UNI,
-	MWIFIEX_EVENT_ID_FW_MIC_ERR_MUL,
-	MWIFIEX_EVENT_ID_FW_BCN_RSSI_LOW,
-	MWIFIEX_EVENT_ID_FW_BCN_RSSI_HIGH,
-	MWIFIEX_EVENT_ID_FW_BCN_SNR_LOW,
-	MWIFIEX_EVENT_ID_FW_BCN_SNR_HIGH,
-	MWIFIEX_EVENT_ID_FW_MAX_FAIL,
-	MWIFIEX_EVENT_ID_FW_DATA_RSSI_LOW,
-	MWIFIEX_EVENT_ID_FW_DATA_RSSI_HIGH,
-	MWIFIEX_EVENT_ID_FW_DATA_SNR_LOW,
-	MWIFIEX_EVENT_ID_FW_DATA_SNR_HIGH,
-	MWIFIEX_EVENT_ID_FW_LINK_QUALITY,
-	MWIFIEX_EVENT_ID_FW_PORT_RELEASE,
-	MWIFIEX_EVENT_ID_FW_PRE_BCN_LOST,
-	MWIFIEX_EVENT_ID_FW_WMM_CONFIG_CHANGE,
-	MWIFIEX_EVENT_ID_FW_HS_WAKEUP,
-	MWIFIEX_EVENT_ID_FW_DS_AWAKE,
-	MWIFIEX_EVENT_ID_FW_BG_SCAN,
-	MWIFIEX_EVENT_ID_FW_WEP_ICV_ERR,
-	MWIFIEX_EVENT_ID_FW_STOP_TX,
-	MWIFIEX_EVENT_ID_FW_START_TX,
-	MWIFIEX_EVENT_ID_FW_BW_CHANGED,
-	MWIFIEX_EVENT_ID_HOSTWAKE_STAIE,
-
-	MWIFIEX_EVENT_ID_DRV_CONNECTED = 0x80000001,
-	MWIFIEX_EVENT_ID_DRV_DEFER_HANDLING,
-	MWIFIEX_EVENT_ID_DRV_HS_ACTIVATED,
-	MWIFIEX_EVENT_ID_DRV_HS_DEACTIVATED,
-	MWIFIEX_EVENT_ID_DRV_OBSS_SCAN_PARAM,
-	MWIFIEX_EVENT_ID_DRV_SCAN_REPORT,
-};
-
 struct mwifiex_fw_image {
 	u8 *helper_buf;
 	u32 helper_len;
@@ -161,13 +124,6 @@ struct mwifiex_fw_image {
 	u32 fw_len;
 };
 
-struct mwifiex_event {
-	u32 bss_index;
-	enum mwifiex_event_id event_id;
-	u32 event_len;
-	u8 event_buf[1];
-};
-
 struct mwifiex_802_11_ssid {
 	u32 ssid_len;
 	u8 ssid[IW_ESSID_MAX_SIZE];
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 2bdecdb..8723c85 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -692,8 +692,6 @@ mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
 	struct ieee_types_assoc_rsp *assoc_rsp;
 	struct mwifiex_bssdescriptor *bss_desc;
 	u8 enable_data = true;
-	u8 event_buf[100];
-	struct mwifiex_event *event = (struct mwifiex_event *) event_buf;
 
 	ENTER();
 
@@ -805,22 +803,16 @@ mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
 	priv->adapter->dbg.num_cmd_assoc_success++;
 
 	PRINTM(MINFO, "ASSOC_RESP: Associated\n");
-	event->bss_index = priv->bss_index;
-	event->event_id = MWIFIEX_EVENT_ID_DRV_CONNECTED;
-	event->event_len = MWIFIEX_MAC_ADDR_LENGTH;
-	memcpy((u8 *) event->event_buf,
-	       (u8 *) priv->curr_bss_params.bss_descriptor.mac_address,
-	       MWIFIEX_MAC_ADDR_LENGTH);
 
 	/* Add the ra_list here for infra mode as there will be only 1 ra
 	   always */
 	mwifiex_ralist_add(priv,
 			   priv->curr_bss_params.bss_descriptor.mac_address);
 
-	mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_DRV_CONNECTED, event);
-
-	/* Send OBSS scan param to the application if available */
-	mwifiex_2040_coex_event(priv);
+	if (!netif_carrier_ok(priv->netdev))
+		netif_carrier_on(priv->netdev);
+	if (netif_queue_stopped(priv->netdev))
+		netif_wake_queue(priv->netdev);
 
 	if (priv->sec_info.ewpa_enabled ||
 			priv->sec_info.wpa_enabled ||
@@ -1486,8 +1478,6 @@ mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
 	struct mwifiex_bssdescriptor *bss_desc;
 	u16 command = le16_to_cpu(resp->command);
 	u16 result = le16_to_cpu(resp->result);
-	u8 event_buf[100];
-	struct mwifiex_event *event = (struct mwifiex_event *) event_buf;
 
 	ENTER();
 
@@ -1548,13 +1538,11 @@ mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
 	       priv->curr_bss_params.bss_descriptor.mac_address[4],
 	       priv->curr_bss_params.bss_descriptor.mac_address[5]);
 
-	event->bss_index = priv->bss_index;
-	event->event_id = MWIFIEX_EVENT_ID_DRV_CONNECTED;
-	event->event_len = MWIFIEX_MAC_ADDR_LENGTH;
-	memcpy((u8 *) event->event_buf,
-	       (u8 *) priv->curr_bss_params.bss_descriptor.mac_address,
-	       MWIFIEX_MAC_ADDR_LENGTH);
-	mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_DRV_CONNECTED, event);
+	if (!netif_carrier_ok(priv->netdev))
+		netif_carrier_on(priv->netdev);
+	if (netif_queue_stopped(priv->netdev))
+		netif_wake_queue(priv->netdev);
+
 	mwifiex_save_curr_bcn(priv);
 
 done:
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 6f03f95..36bb35d 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -777,7 +777,6 @@ mwifiex_init_priv_params(struct mwifiex_private *priv, struct net_device *dev)
 	priv->current_key_index = 0;
 	priv->rate_index = AUTO_RATE;
 	priv->media_connected = false;
-	priv->is_adhoc_link_sensed = false;
 	memset(&priv->nick_name, 0, sizeof(priv->nick_name));
 	priv->num_tx_timeout = 0;
 	priv->workqueue = create_singlethread_workqueue("cfg80211_wq");
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 8e9fb0b..5b1d557 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -421,7 +421,6 @@ struct mwifiex_private {
 	struct dentry *dfs_dev_dir;
 #endif
 	u8 nick_name[16];
-	bool is_adhoc_link_sensed;
 	struct iw_statistics w_stats;
 	u16 w_stats_wait_q_woken;
 	wait_queue_head_t w_stats_wait_q;
@@ -658,17 +657,10 @@ enum mwifiex_status mwifiex_recv_complete(struct mwifiex_adapter *,
 
 enum mwifiex_status mwifiex_recv_packet(struct mwifiex_adapter *,
 					struct mwifiex_buffer *mbuf);
-enum mwifiex_status mwifiex_recv_event(struct mwifiex_private *priv,
-				       enum mwifiex_event_id event_id,
-					struct mwifiex_event *event);
 
 struct mwifiex_buffer *mwifiex_alloc_buffer_skb(int size);
 void mwifiex_free_buffer_skb(struct mwifiex_buffer *mbuf);
 
-enum mwifiex_status
-mwifiex_process_recv_event(struct mwifiex_adapter *adapter,
-				struct mwifiex_event *event);
-
 void mwifiex_init_adapter(struct mwifiex_adapter *adapter);
 void mwifiex_delete_bss_prio_tbl(struct mwifiex_private *priv);
 
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 23be1de..29d457a 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -2942,8 +2942,13 @@ mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
 					       ioctl_buf,
 					       MWIFIEX_STATUS_SUCCESS);
 		}
-		mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_DRV_SCAN_REPORT,
-				   NULL);
+		if (priv->report_scan_result)
+			priv->report_scan_result = false;
+		if (priv->scan_pending_on_block) {
+			priv->scan_pending_on_block = false;
+			up(&priv->async_sem);
+		}
+
 	} else {
 		/* Get scan command from scan_pending_q and put to
 		   cmd_pending_q */
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index aba9778..a83c72a 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -90,8 +90,12 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv,
 		spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
 		adapter->scan_processing = false;
 		spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
-		mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_DRV_SCAN_REPORT,
-				   NULL);
+		if (priv->report_scan_result)
+			priv->report_scan_result = false;
+		if (priv->scan_pending_on_block) {
+			priv->scan_pending_on_block = false;
+			up(&priv->async_sem);
+		}
 		break;
 
 	case HostCmd_CMD_MAC_CONTROL:
@@ -1412,7 +1416,6 @@ mwifiex_process_sta_cmdresp(struct mwifiex_private *priv,
 		break;
 	case HostCmd_CMD_802_11_BG_SCAN_QUERY:
 		ret = mwifiex_ret_802_11_scan(priv, resp, ioctl_buf);
-		mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_FW_BG_SCAN, NULL);
 		PRINTM(MINFO, "CMD_RESP: BG_SCAN result is ready!\n");
 		break;
 	case HostCmd_CMD_TXPWR_CFG:
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index 0c127f4..47140dc 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -123,43 +123,24 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv)
 		LEAVE();
 		return;
 	}
-	mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_FW_DISCONNECTED, NULL);
-
-	LEAVE();
-}
-
-/*
- * This function sends the OBSS scan parameters to the application.
- *
- * The scan parameters are copied into a new event body and the event
- * is sent to the application.
- */
-void
-mwifiex_2040_coex_event(struct mwifiex_private *priv)
-{
-	u8 event_buf[100];
-	struct mwifiex_event *event = (struct mwifiex_event *) event_buf;
-	u8 ele_len;
-
-	ENTER();
-
-	if (priv->curr_bss_params.bss_descriptor.bcn_obss_scan &&
-	    priv->curr_bss_params.bss_descriptor.bcn_obss_scan->
-	    ieee_hdr.element_id == WLAN_EID_OVERLAP_BSS_SCAN_PARAM) {
-		ele_len =
-			priv->curr_bss_params.bss_descriptor.
-			bcn_obss_scan->ieee_hdr.len;
-		event->bss_index = priv->bss_index;
-		event->event_id = MWIFIEX_EVENT_ID_DRV_OBSS_SCAN_PARAM;
-		/* Copy OBSS scan parameters */
-		memcpy((u8 *) event->event_buf,
-		       (u8 *) &priv->curr_bss_params.bss_descriptor.
-		       bcn_obss_scan->obss_scan, ele_len);
-		event->event_len = ele_len;
-		mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_DRV_OBSS_SCAN_PARAM,
-				   event);
+	priv->media_connected = false;
+	if (!priv->disconnect) {
+		priv->disconnect = 1;
+		PRINTM(MINFO, "Successfully disconnected from %pM:"
+				" Reason code %d\n", priv->cfg_bssid,
+				WLAN_REASON_DEAUTH_LEAVING);
+		cfg80211_disconnected(priv->netdev,
+				WLAN_REASON_DEAUTH_LEAVING, NULL, 0,
+				GFP_KERNEL);
+		queue_work(priv->workqueue, &priv->cfg_workqueue);
 	}
-
+	if (!netif_queue_stopped(priv->netdev))
+		netif_stop_queue(priv->netdev);
+	if (netif_carrier_ok(priv->netdev))
+		netif_carrier_off(priv->netdev);
+	/* Reset wireless stats signal info */
+	priv->w_stats.qual.level = 0;
+	priv->w_stats.qual.noise = 0;
 	LEAVE();
 }
 
@@ -220,8 +201,6 @@ mwifiex_process_sta_event(struct mwifiex_private *priv)
 	struct mwifiex_adapter *adapter = priv->adapter;
 	enum mwifiex_status ret = MWIFIEX_STATUS_SUCCESS;
 	u32 eventcause = adapter->event_cause;
-	u8 event_buf[100];
-	struct mwifiex_event *event = (struct mwifiex_event *) event_buf;
 
 	ENTER();
 
@@ -232,9 +211,10 @@ mwifiex_process_sta_event(struct mwifiex_private *priv)
 		break;
 	case EVENT_LINK_SENSED:
 		PRINTM(MEVENT, "EVENT: LINK_SENSED\n");
-		priv->adhoc_is_link_sensed = true;
-		mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_FW_ADHOC_LINK_SENSED,
-				NULL);
+		if (!netif_carrier_ok(priv->netdev))
+			netif_carrier_on(priv->netdev);
+		if (netif_queue_stopped(priv->netdev))
+			netif_wake_queue(priv->netdev);
 		break;
 
 	case EVENT_DEAUTHENTICATED:
@@ -302,8 +282,6 @@ mwifiex_process_sta_event(struct mwifiex_private *priv)
 		PRINTM(MEVENT, "EVENT: DS_AWAKE\n");
 		if (adapter->is_deep_sleep)
 			adapter->is_deep_sleep = false;
-
-		mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_FW_DS_AWAKE, NULL);
 		break;
 
 	case EVENT_HS_ACT_REQ:
@@ -315,14 +293,10 @@ mwifiex_process_sta_event(struct mwifiex_private *priv)
 
 	case EVENT_MIC_ERR_UNICAST:
 		PRINTM(MEVENT, "EVENT: UNICAST MIC ERROR\n");
-		mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_FW_MIC_ERR_UNI,
-				   NULL);
 		break;
 
 	case EVENT_MIC_ERR_MULTICAST:
 		PRINTM(MEVENT, "EVENT: MULTICAST MIC ERROR\n");
-		mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_FW_MIC_ERR_MUL,
-				   NULL);
 		break;
 	case EVENT_MIB_CHANGED:
 	case EVENT_INIT_DONE:
@@ -332,8 +306,10 @@ mwifiex_process_sta_event(struct mwifiex_private *priv)
 		PRINTM(MEVENT, "EVENT: ADHOC_BCN_LOST\n");
 		priv->adhoc_is_link_sensed = false;
 		mwifiex_clean_txrx(priv);
-		mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_FW_ADHOC_LINK_LOST,
-				   NULL);
+		if (!netif_queue_stopped(priv->netdev))
+			netif_stop_queue(priv->netdev);
+		if (netif_carrier_ok(priv->netdev))
+			netif_carrier_off(priv->netdev);
 		break;
 
 	case EVENT_BG_SCAN_REPORT:
@@ -350,8 +326,6 @@ mwifiex_process_sta_event(struct mwifiex_private *priv)
 
 	case EVENT_PORT_RELEASE:
 		PRINTM(MEVENT, "EVENT: PORT RELEASE\n");
-		mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_FW_PORT_RELEASE,
-				   NULL);
 		break;
 
 	case EVENT_WMM_STATUS_CHANGE:
@@ -362,57 +336,36 @@ mwifiex_process_sta_event(struct mwifiex_private *priv)
 
 	case EVENT_RSSI_LOW:
 		PRINTM(MEVENT, "EVENT: Beacon RSSI_LOW\n");
-		mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_FW_BCN_RSSI_LOW,
-				   NULL);
 		break;
 	case EVENT_SNR_LOW:
 		PRINTM(MEVENT, "EVENT: Beacon SNR_LOW\n");
-		mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_FW_BCN_SNR_LOW,
-				   NULL);
 		break;
 	case EVENT_MAX_FAIL:
 		PRINTM(MEVENT, "EVENT: MAX_FAIL\n");
-		mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_FW_MAX_FAIL, NULL);
 		break;
 	case EVENT_RSSI_HIGH:
 		PRINTM(MEVENT, "EVENT: Beacon RSSI_HIGH\n");
-		mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_FW_BCN_RSSI_HIGH,
-				   NULL);
 		break;
 	case EVENT_SNR_HIGH:
 		PRINTM(MEVENT, "EVENT: Beacon SNR_HIGH\n");
-		mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_FW_BCN_SNR_HIGH,
-				   NULL);
 		break;
 	case EVENT_DATA_RSSI_LOW:
 		PRINTM(MEVENT, "EVENT: Data RSSI_LOW\n");
-		mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_FW_DATA_RSSI_LOW,
-				   NULL);
 		break;
 	case EVENT_DATA_SNR_LOW:
 		PRINTM(MEVENT, "EVENT: Data SNR_LOW\n");
-		mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_FW_DATA_SNR_LOW,
-				   NULL);
 		break;
 	case EVENT_DATA_RSSI_HIGH:
 		PRINTM(MEVENT, "EVENT: Data RSSI_HIGH\n");
-		mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_FW_DATA_RSSI_HIGH,
-				   NULL);
 		break;
 	case EVENT_DATA_SNR_HIGH:
 		PRINTM(MEVENT, "EVENT: Data SNR_HIGH\n");
-		mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_FW_DATA_SNR_HIGH,
-				   NULL);
 		break;
 	case EVENT_LINK_QUALITY:
 		PRINTM(MEVENT, "EVENT: Link Quality\n");
-		mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_FW_LINK_QUALITY,
-				   NULL);
 		break;
 	case EVENT_PRE_BEACON_LOST:
 		PRINTM(MEVENT, "EVENT: Pre-Beacon Lost\n");
-		mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_FW_PRE_BCN_LOST,
-				   NULL);
 		break;
 	case EVENT_IBSS_COALESCED:
 		PRINTM(MEVENT, "EVENT: IBSS_COALESCED\n");
@@ -448,41 +401,17 @@ mwifiex_process_sta_event(struct mwifiex_private *priv)
 
 	case EVENT_WEP_ICV_ERR:
 		PRINTM(MEVENT, "EVENT: WEP ICV error\n");
-		event->bss_index = priv->bss_index;
-		event->event_id = MWIFIEX_EVENT_ID_FW_WEP_ICV_ERR;
-		event->event_len = sizeof(struct mwifiex_event_wep_icv_err);
-		memcpy((u8 *) event->event_buf, adapter->event_body,
-		       event->event_len);
-		mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_FW_WEP_ICV_ERR,
-				   event);
 		break;
 
 	case EVENT_BW_CHANGE:
 		PRINTM(MEVENT, "EVENT: BW Change\n");
-		event->bss_index = priv->bss_index;
-		event->event_id = MWIFIEX_EVENT_ID_FW_BW_CHANGED;
-		event->event_len = sizeof(u8);
-		/* Copy event body from the event buffer */
-		memcpy((u8 *) event->event_buf, adapter->event_body,
-		       event->event_len);
-		mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_FW_BW_CHANGED,
-				   event);
 		break;
 
 	case EVENT_HOSTWAKE_STAIE:
 		PRINTM(MEVENT, "EVENT: HOSTWAKE_STAIE %d\n", eventcause);
-		event->bss_index = priv->bss_index;
-		event->event_id = MWIFIEX_EVENT_ID_HOSTWAKE_STAIE;
-		event->event_len = sizeof(u32);
-		memcpy((u8 *) event->event_buf, adapter->event_body,
-		       event->event_len);
-
-		mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_HOSTWAKE_STAIE,
-				   event);
 		break;
 	default:
 		PRINTM(MEVENT, "EVENT: unknown event id: %#x\n", eventcause);
-		mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_FW_UNKNOWN, NULL);
 		break;
 	}
 
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index f1676bb..35df4c9 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -6033,8 +6033,6 @@ mwifiex_scan_ioctl(struct mwifiex_adapter *adapter,
 
 	if (priv->scan_block && ioctl_req->action == MWIFIEX_ACT_SET) {
 		PRINTM(MCMND, "Scan is blocked during association...\n");
-		/* mwifiex_recv_event(priv,  MWIFIEX_EVENT_ID_DRV_SCAN_REPORT,
-			NULL); */
 		LEAVE();
 		return status;
 	}
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index 9ef5b74..55d912d 100644
--- a/drivers/net/wireless/mwifiex/util.c
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -470,9 +470,7 @@ mwifiex_send_packet_complete(struct mwifiex_adapter *adapter,
 					if ((GET_BSS_ROLE(adapter->priv[i]) ==
 					     MWIFIEX_BSS_ROLE_STA)
 					    && (adapter->priv[i]->
-						media_connected
-						|| priv->
-						is_adhoc_link_sensed)) {
+						media_connected)) {
 						if (netif_queue_stopped
 						    (adapter->priv[i]->netdev))
 							netif_wake_queue
@@ -619,144 +617,6 @@ mwifiex_print(u32 level, s8 *pformat, ...)
 EXPORT_SYMBOL_GPL(mwifiex_print);
 
 /*
- * This function handles received events.
- *
- * Handling may include updating the traffic queue status, setting
- * driver variables, updating statistics, sending a standard or
- * custom wireless event to application, or broadcasting a pass
- * through event via netlink socket.
- */
-enum mwifiex_status
-mwifiex_process_recv_event(struct mwifiex_adapter *adapter,
-				struct mwifiex_event *event)
-{
-	struct mwifiex_private *priv = NULL;
-
-	ENTER();
-
-	PRINTM(MEVENT, "event id:0x%x\n", event->event_id);
-	priv = mwifiex_bss_index_to_priv(adapter, event->bss_index);
-	if (priv == NULL) {
-		PRINTM(MERROR, "%s: priv is null\n", __func__);
-		goto done;
-	}
-	switch (event->event_id) {
-	case MWIFIEX_EVENT_ID_FW_ADHOC_LINK_SENSED:
-		priv->is_adhoc_link_sensed = true;
-		if (!netif_carrier_ok(priv->netdev))
-			netif_carrier_on(priv->netdev);
-		if (netif_queue_stopped(priv->netdev))
-			netif_wake_queue(priv->netdev);
-		break;
-	case MWIFIEX_EVENT_ID_FW_ADHOC_LINK_LOST:
-		if (!netif_queue_stopped(priv->netdev))
-			netif_stop_queue(priv->netdev);
-		if (netif_carrier_ok(priv->netdev))
-			netif_carrier_off(priv->netdev);
-		priv->is_adhoc_link_sensed = false;
-		break;
-	case MWIFIEX_EVENT_ID_DRV_CONNECTED:
-		priv->media_connected = true;
-		if (!netif_carrier_ok(priv->netdev))
-			netif_carrier_on(priv->netdev);
-		if (netif_queue_stopped(priv->netdev))
-			netif_wake_queue(priv->netdev);
-		break;
-	case MWIFIEX_EVENT_ID_DRV_SCAN_REPORT:
-		PRINTM(MCMND, "Scan report\n");
-		if (priv->report_scan_result)
-			priv->report_scan_result = false;
-		if (priv->scan_pending_on_block) {
-			priv->scan_pending_on_block = false;
-			up(&priv->async_sem);
-		}
-		break;
-	case MWIFIEX_EVENT_ID_FW_DISCONNECTED:
-		priv->media_connected = false;
-		if (!priv->disconnect) {
-			priv->disconnect = 1;
-			PRINTM(MINFO, "Successfully disconnected from %pM:"
-					" Reason code %d\n", priv->cfg_bssid,
-					WLAN_REASON_DEAUTH_LEAVING);
-			cfg80211_disconnected(priv->netdev,
-					WLAN_REASON_DEAUTH_LEAVING, NULL, 0,
-					GFP_KERNEL);
-			queue_work(priv->workqueue, &priv->cfg_workqueue);
-		}
-		if (!netif_queue_stopped(priv->netdev))
-			netif_stop_queue(priv->netdev);
-		if (netif_carrier_ok(priv->netdev))
-			netif_carrier_off(priv->netdev);
-		/* Reset wireless stats signal info */
-		priv->w_stats.qual.level = 0;
-		priv->w_stats.qual.noise = 0;
-		break;
-	case MWIFIEX_EVENT_ID_FW_WEP_ICV_ERR:
-		DBG_HEXDUMP(MCMD_D, "WEP ICV error", event->event_buf,
-			    event->event_len);
-		break;
-
-	case MWIFIEX_EVENT_ID_DRV_DEFER_HANDLING:
-		queue_work(adapter->workqueue, &adapter->main_work);
-		break;
-	case MWIFIEX_EVENT_ID_FW_BG_SCAN:
-		break;
-	case MWIFIEX_EVENT_ID_FW_STOP_TX:
-		netif_carrier_off(priv->netdev);
-		break;
-	case MWIFIEX_EVENT_ID_FW_START_TX:
-		netif_carrier_on(priv->netdev);
-		break;
-	case MWIFIEX_EVENT_ID_FW_HS_WAKEUP:
-		/* simulate HSCFG_CANCEL command */
-		mwifiex_cancel_hs(priv, MWIFIEX_NO_WAIT);
-		priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
-		break;
-	case MWIFIEX_EVENT_ID_DRV_HS_ACTIVATED:
-		priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
-		if (priv) {
-			adapter->hs_activated = true;
-			adapter->hs_activate_wait_q_woken = true;
-			wake_up_interruptible(&adapter->hs_activate_wait_q);
-		}
-		break;
-	case MWIFIEX_EVENT_ID_DRV_HS_DEACTIVATED:
-		priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
-		if (priv)
-			adapter->hs_activated = false;
-		break;
-
-	/* These events might be interesting to some userland? */
-	case MWIFIEX_EVENT_ID_DRV_OBSS_SCAN_PARAM:
-	case MWIFIEX_EVENT_ID_FW_BW_CHANGED:
-	case MWIFIEX_EVENT_ID_HOSTWAKE_STAIE:
-	case MWIFIEX_EVENT_ID_FW_MIC_ERR_UNI:
-	case MWIFIEX_EVENT_ID_FW_MIC_ERR_MUL:
-	case MWIFIEX_EVENT_ID_FW_BCN_RSSI_LOW:
-	case MWIFIEX_EVENT_ID_FW_BCN_RSSI_HIGH:
-	case MWIFIEX_EVENT_ID_FW_BCN_SNR_LOW:
-	case MWIFIEX_EVENT_ID_FW_BCN_SNR_HIGH:
-	case MWIFIEX_EVENT_ID_FW_MAX_FAIL:
-	case MWIFIEX_EVENT_ID_FW_DATA_RSSI_LOW:
-	case MWIFIEX_EVENT_ID_FW_DATA_SNR_LOW:
-	case MWIFIEX_EVENT_ID_FW_DATA_RSSI_HIGH:
-	case MWIFIEX_EVENT_ID_FW_DATA_SNR_HIGH:
-	case MWIFIEX_EVENT_ID_FW_LINK_QUALITY:
-	case MWIFIEX_EVENT_ID_FW_PORT_RELEASE:
-	case MWIFIEX_EVENT_ID_FW_PRE_BCN_LOST:
-	case MWIFIEX_EVENT_ID_FW_DS_AWAKE:
-	case MWIFIEX_EVENT_ID_FW_WMM_CONFIG_CHANGE:
-		break;
-
-	default:
-		break;
-	}
-done:
-	LEAVE();
-	return MWIFIEX_STATUS_SUCCESS;
-}
-
-/*
  * This function handles get BSS information IOCTL responses.
  *
  * The following information type is currently supported -
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index cdb0e58..2a403ae 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -895,8 +895,6 @@ mwifiex_ret_wmm_get_status(struct mwifiex_private *priv,
 	mwifiex_wmm_setup_queue_priorities(priv, wmm_param_ie);
 	mwifiex_wmm_setup_ac_downgrade(priv);
 
-	mwifiex_recv_event(priv, MWIFIEX_EVENT_ID_FW_WMM_CONFIG_CHANGE, NULL);
-
 	LEAVE();
 	return MWIFIEX_STATUS_SUCCESS;
 }
-- 
1.7.0.2


^ permalink raw reply related

* [PATCH 1/2] mwifiex: remove un-needed functions
From: Bing Zhao @ 2010-12-29  1:59 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Johannes Berg, Amitkumar Karwar, Kiran Divekar,
	Frank Huang, Bing Zhao

From: Kiran Divekar <dkiran@marvell.com>

There are a few dummy functions that are useless.
This patch removes them.

Signed-off-by: Kiran Divekar <dkiran@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/mwifiex/11n_rxreorder.c |   26 -----------------------
 drivers/net/wireless/mwifiex/join.c          |    8 ++++--
 drivers/net/wireless/mwifiex/sta_cmdresp.c   |   14 ------------
 drivers/net/wireless/mwifiex/sta_event.c     |   29 +++++++------------------
 drivers/net/wireless/mwifiex/wmm.c           |   26 -----------------------
 drivers/net/wireless/mwifiex/wmm.h           |    2 -
 6 files changed, 13 insertions(+), 92 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c
index 8da7a29..dcfcb99 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c
@@ -97,21 +97,6 @@ mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv,
 }
 
 /*
- * This function dumps the complete Rx reorder table.
- */
-static void
-mwifiex_11n_display_tbl_ptr(struct mwifiex_adapter *adapter,
-			    struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr)
-{
-	ENTER();
-
-	DBG_HEXDUMP(MDAT_D, "Reorder ptr", rx_reor_tbl_ptr->rx_reorder_ptr,
-		    rx_reor_tbl_ptr->win_size);
-
-	LEAVE();
-}
-
-/*
  * This function dispatches all packets in the Rx reorder table until
  * a hole is found.
  *
@@ -264,9 +249,6 @@ mwifiex_flush_data(unsigned long context)
 		(struct reorder_tmr_cnxt *) context;
 	int start_win;
 
-	mwifiex_11n_display_tbl_ptr(reorder_cnxt->priv->adapter,
-				    reorder_cnxt->ptr);
-
 	start_win = mwifiex_11n_find_last_seq_num(reorder_cnxt->ptr);
 	if (start_win >= 0) {
 		PRINTM(MINFO, "Flush data %d\n", start_win);
@@ -275,9 +257,6 @@ mwifiex_flush_data(unsigned long context)
 				((reorder_cnxt->ptr->start_win +
 				  start_win + 1) & (MAX_TID_VALUE - 1)));
 	}
-
-	mwifiex_11n_display_tbl_ptr(reorder_cnxt->priv->adapter,
-				    reorder_cnxt->ptr);
 }
 
 /*
@@ -508,7 +487,6 @@ mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
 	struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr;
 	int start_win, end_win, win_size;
 	enum mwifiex_status ret = MWIFIEX_STATUS_SUCCESS;
-	struct mwifiex_adapter *adapter = priv->adapter;
 	u16 pkt_index = 0;
 
 	ENTER();
@@ -609,15 +587,11 @@ mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
 			rx_reor_tbl_ptr->rx_reorder_ptr[pkt_index] = payload;
 		}
 
-		mwifiex_11n_display_tbl_ptr(adapter, rx_reor_tbl_ptr);
-
 		/*
 		 * Dispatch all packets sequentially from start_win until a
 		 * hole is found and adjust the start_win appropriately
 		 */
 		ret = mwifiex_11n_scan_and_dispatch(priv, rx_reor_tbl_ptr);
-
-		mwifiex_11n_display_tbl_ptr(adapter, rx_reor_tbl_ptr);
 	}
 
 	LEAVE();
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 9504107..2bdecdb 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -773,14 +773,16 @@ mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
 	if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled)
 		priv->wpa_is_gtk_set = false;
 
-	if (priv->wmm_enabled)
+	if (priv->wmm_enabled) {
 		/* Don't re-enable carrier until we get the WMM_GET_STATUS
 		   event */
 		enable_data = false;
-	else
+	} else {
 		/* Since WMM is not enabled, setup the queues with the
 		   defaults */
-		mwifiex_wmm_setup_queues(priv);
+		mwifiex_wmm_setup_queue_priorities(priv, NULL);
+		mwifiex_wmm_setup_ac_downgrade(priv);
+	}
 
 	if (enable_data)
 		PRINTM(MINFO, "Post association, re-enabling data flow\n");
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index c1b646e..aba9778 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -189,19 +189,6 @@ mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv,
 }
 
 /*
- * This function handles the command response of MAC control
- */
-static enum mwifiex_status
-mwifiex_ret_mac_control(struct mwifiex_private *priv,
-			struct host_cmd_ds_command *resp,
-			struct mwifiex_ioctl_req *ioctl_buf)
-{
-	ENTER();
-	LEAVE();
-	return MWIFIEX_STATUS_SUCCESS;
-}
-
-/*
  * This function handles the command response of set/get SNMP
  * MIB parameters.
  *
@@ -1408,7 +1395,6 @@ mwifiex_process_sta_cmdresp(struct mwifiex_private *priv,
 		ret = mwifiex_ret_get_hw_spec(priv, resp, ioctl_buf);
 		break;
 	case HostCmd_CMD_MAC_CONTROL:
-		ret = mwifiex_ret_mac_control(priv, resp, ioctl_buf);
 		break;
 	case HostCmd_CMD_802_11_MAC_ADDRESS:
 		ret = mwifiex_ret_802_11_mac_address(priv, resp, ioctl_buf);
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index 4cd4169..0c127f4 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -129,22 +129,6 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv)
 }
 
 /*
- * This function handles link lost, deauthenticated and disassociated
- * events.
- *
- * If media status was connected, it resets the connection state.
- */
-static void
-mwifiex_handle_disconnect_event(struct mwifiex_private *priv)
-{
-	ENTER();
-	if (priv->media_connected)
-		mwifiex_reset_connect_state(priv);
-
-	LEAVE();
-}
-
-/*
  * This function sends the OBSS scan parameters to the application.
  *
  * The scan parameters are copied into a new event body and the event
@@ -256,19 +240,22 @@ mwifiex_process_sta_event(struct mwifiex_private *priv)
 	case EVENT_DEAUTHENTICATED:
 		PRINTM(MEVENT, "EVENT: Deauthenticated\n");
 		adapter->dbg.num_event_deauth++;
-		mwifiex_handle_disconnect_event(priv);
+		if (priv->media_connected)
+			mwifiex_reset_connect_state(priv);
 		break;
 
 	case EVENT_DISASSOCIATED:
 		PRINTM(MEVENT, "EVENT: Disassociated\n");
 		adapter->dbg.num_event_disassoc++;
-		mwifiex_handle_disconnect_event(priv);
+		if (priv->media_connected)
+			mwifiex_reset_connect_state(priv);
 		break;
 
 	case EVENT_LINK_LOST:
 		PRINTM(MEVENT, "EVENT: Link lost\n");
 		adapter->dbg.num_event_link_lost++;
-		mwifiex_handle_disconnect_event(priv);
+		if (priv->media_connected)
+			mwifiex_reset_connect_state(priv);
 		break;
 
 	case EVENT_PS_SLEEP:
@@ -369,8 +356,8 @@ mwifiex_process_sta_event(struct mwifiex_private *priv)
 
 	case EVENT_WMM_STATUS_CHANGE:
 		PRINTM(MEVENT, "EVENT: WMM status changed\n");
-		ret = (enum mwifiex_status)
-			mwifiex_cmd_wmm_status_change(priv);
+		ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_WMM_GET_STATUS,
+				0, 0, NULL, NULL);
 		break;
 
 	case EVENT_RSSI_LOW:
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index 4cdaaa4..cdb0e58 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -506,32 +506,6 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter)
 }
 
 /*
- * This function sets up the queue priorities and downgrades any queues
- * as required by the WMM information.
- *
- * This also sets up default values if WMM is not active for this association.
- */
-void
-mwifiex_wmm_setup_queues(struct mwifiex_private *priv)
-{
-	ENTER();
-	mwifiex_wmm_setup_queue_priorities(priv, NULL);
-	mwifiex_wmm_setup_ac_downgrade(priv);
-	LEAVE();
-}
-
-/*
- * This function sends a command to firmware to retrieve the current WMM
- * status.
- */
-int
-mwifiex_cmd_wmm_status_change(struct mwifiex_private *priv)
-{
-	return mwifiex_prepare_cmd(priv, HostCmd_CMD_WMM_GET_STATUS, 0, 0, NULL,
-				   NULL);
-}
-
-/*
  * This function checks if WMM Tx queue is empty.
  */
 int
diff --git a/drivers/net/wireless/mwifiex/wmm.h b/drivers/net/wireless/mwifiex/wmm.h
index cd6d5cf..88f4480 100644
--- a/drivers/net/wireless/mwifiex/wmm.h
+++ b/drivers/net/wireless/mwifiex/wmm.h
@@ -89,7 +89,6 @@ void mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter,
 void mwifiex_wmm_delete_all_ralist(struct mwifiex_private *priv);
 void mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra);
 
-int mwifiex_cmd_wmm_status_change(struct mwifiex_private *priv);
 int mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter);
 void mwifiex_wmm_cleanup_queues(struct mwifiex_private *priv);
 void mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter);
@@ -100,7 +99,6 @@ u8 mwifiex_wmm_compute_drv_pkt_delay(struct mwifiex_private *priv,
 					     const struct mwifiex_buffer
 					     *mbuf);
 void mwifiex_wmm_init(struct mwifiex_adapter *adapter);
-extern void mwifiex_wmm_setup_queues(struct mwifiex_private *priv);
 void mwifiex_wmm_default_queue_priorities(struct mwifiex_private *priv);
 
 extern u32 mwifiex_wmm_process_association_req(struct mwifiex_private *priv,
-- 
1.7.0.2


^ permalink raw reply related

* [PATCHv2 1/1] mac80211: Fix mesh portal communication with other mesh nodes.
From: Joel A Fernandes @ 2010-12-29  1:28 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, devel, Johannes Berg

Fixed a bug where if a mesh interface has a different MAC address from its bridge
interface, then it would not be able to send data traffic to any other mesh node.
This also adds support for communication between mesh nodes and external bridged
nodes by using a 6 address format if the source is a node within the mesh and the
destination is an external node proxied by a mesh portal.

Signed-off-by: Joel A Fernandes <agnel.joel@gmail.com>
---
Sorry I added the mailing list and maintainer email addresses to the "To" field
the last time I sent this patch. I apologise for any confusion. Thank you.
---
 net/mac80211/tx.c |   14 ++++++++++----
 1 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index ad5bc90..8f78a26 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1751,6 +1751,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
 	__le16 fc;
 	struct ieee80211_hdr hdr;
 	struct ieee80211s_hdr mesh_hdr __maybe_unused;
+	struct mesh_path *mppath = NULL;
 	const u8 *encaps_data;
 	int encaps_len, skip_header_bytes;
 	int nh_pos, h_pos;
@@ -1811,16 +1812,23 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
 			ret = NETDEV_TX_OK;
 			goto fail;
 		}
+		if (!is_multicast_ether_addr(skb->data))
+			mppath = mpp_path_lookup(skb->data, sdata);
 
+		/*
+		 * Do not use address extension, if it is a packet from
+		 * the same interface and the destination is not being
+		 * proxied by any other mest point.
+		 */
 		if (compare_ether_addr(sdata->vif.addr,
-				       skb->data + ETH_ALEN) == 0) {
+				       skb->data + ETH_ALEN) == 0 &&
+		    (!mppath || !compare_ether_addr(mppath->mpp, skb->data))) {
 			hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc,
 					skb->data, skb->data + ETH_ALEN);
 			meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr,
 					sdata, NULL, NULL);
 		} else {
 			/* packet from other interface */
-			struct mesh_path *mppath;
 			int is_mesh_mcast = 1;
 			const u8 *mesh_da;
 
@@ -1831,8 +1839,6 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
 			else {
 				static const u8 bcast[ETH_ALEN] =
 					{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-
-				mppath = mpp_path_lookup(skb->data, sdata);
 				if (mppath) {
 					/* RA TA mDA mSA AE:DA SA */
 					mesh_da = mppath->mpp;

^ permalink raw reply related

* [PATCH 1/1] mac80211: Fix mesh portal communication with other mesh nodes.
From: Joel A Fernandes @ 2010-12-29  1:18 UTC (permalink / raw)
  To: John W. Linville, linux-wireless, devel, Johannes Berg

Fixed a bug where if a mesh interface has a different MAC address from its bridge
interface, then it would not be able to send data traffic to any other mesh node.
This also adds support for communication between mesh nodes and external bridged
nodes by using a 6 address format if the source is a node within the mesh and the
destination is an external node proxied by a mesh portal.

Signed-off-by: Joel A Fernandes <agnel.joel@gmail.com>
---
 net/mac80211/tx.c |   14 ++++++++++----
 1 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index ad5bc90..8f78a26 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1751,6 +1751,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
 	__le16 fc;
 	struct ieee80211_hdr hdr;
 	struct ieee80211s_hdr mesh_hdr __maybe_unused;
+	struct mesh_path *mppath = NULL;
 	const u8 *encaps_data;
 	int encaps_len, skip_header_bytes;
 	int nh_pos, h_pos;
@@ -1811,16 +1812,23 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
 			ret = NETDEV_TX_OK;
 			goto fail;
 		}
+		if (!is_multicast_ether_addr(skb->data))
+			mppath = mpp_path_lookup(skb->data, sdata);
 
+		/*
+		 * Do not use address extension, if it is a packet from
+		 * the same interface and the destination is not being
+		 * proxied by any other mest point.
+		 */
 		if (compare_ether_addr(sdata->vif.addr,
-				       skb->data + ETH_ALEN) == 0) {
+				       skb->data + ETH_ALEN) == 0 &&
+		    (!mppath || !compare_ether_addr(mppath->mpp, skb->data))) {
 			hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc,
 					skb->data, skb->data + ETH_ALEN);
 			meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr,
 					sdata, NULL, NULL);
 		} else {
 			/* packet from other interface */
-			struct mesh_path *mppath;
 			int is_mesh_mcast = 1;
 			const u8 *mesh_da;
 
@@ -1831,8 +1839,6 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
 			else {
 				static const u8 bcast[ETH_ALEN] =
 					{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-
-				mppath = mpp_path_lookup(skb->data, sdata);
 				if (mppath) {
 					/* RA TA mDA mSA AE:DA SA */
 					mesh_da = mppath->mpp;

^ permalink raw reply related

* Re: printk %pV compatibility in b43 and ath for compat-wireless
From: Nick Leverton @ 2010-12-29  1:04 UTC (permalink / raw)
  To: linux-wireless
In-Reply-To: <4D19118D.6040202@lwfinger.net>

In article <4D19118D.6040202@lwfinger.net>,
Larry Finger  <Larry.Finger@lwfinger.net> wrote:
>-=-=-=-=-=-
>
>On 12/27/2010 12:05 PM, Nick Leverton wrote:
>> 
>> Dec 23 21:10:46 nickl kernel: [688182.007780] Broadcom 43xx driver loaded [ 
>> Features: PMNLS, Firmware-ID: FW13 ]
>> Dec 23 21:10:50 nickl kernel: [688186.100195] b43-phy0: f535bb54
>> Dec 23 21:11:09 nickl kernel: [688205.048054] b43-phy0: f4a3bb54
>> Dec 23 21:11:31 nickl kernel: [688225.667842] b43-phy0 ERROR: f56a5f34
>
>These changes were in commit #5b736d42.
>
>I cannot fix them in compat-wireless, but I think I know the origin of those
>errors. At present, b43 is not setting up the transmit header correctly for N
>PHYs. Whenever, the rate-setting mechanism tries an OFDM rate, one of these
>errors will occur. We are working on modifications to the driver to fix this.
>Until we get that done, issue an 'iwconfig wlan0 rate 11M' to lock the interface
>at 11 Mb/s.
>
>The attached patch can be reverse-applied to fix the driver.

That's super, thankyou - fixed the message format, rate-limit then stops
the error reports and and also improved the stability !  I'll see if it
can keep an SSH session up overnight, but it's looking very good so far.
This is a 14e4:4328 device in a 32bit Dell Latitude.

Now reporting (must get around to adding DEBUG to the driver):

Dec 29 00:00:36 nickl kernel: [1127991.569823] b43-pci-bridge 0000:0c:00.0: PCI INT A -> GSI 17 (level, low) -> IRQ 17
Dec 29 00:00:36 nickl kernel: [1127991.637758] ssb: Sonics Silicon Backplane found on PCI device 0000:0c:00.0
Dec 29 00:00:36 nickl kernel: [1127991.662341] b43-phy0: Broadcom 4321 WLAN found (core revision 12)
Dec 29 00:00:36 nickl kernel: [1127991.732169] Registered led device: b43-phy0::tx
Dec 29 00:00:36 nickl kernel: [1127991.732213] Registered led device: b43-phy0::rx
Dec 29 00:00:36 nickl kernel: [1127991.732255] Registered led device: b43-phy0::radio
Dec 29 00:00:36 nickl kernel: [1127991.732292] Broadcom 43xx driver loaded [ Features: PMNLS, Firmware-ID: FW13 ]
Dec 29 00:00:41 nickl kernel: [1127996.256626] b43-phy0: Loading firmware version 478.104 (2008-07-01 00:50:23)
Dec 29 00:00:41 nickl kernel: [1127996.353560] ADDRCONF(NETDEV_UP): wlan0: link is not ready
Dec 29 00:00:52 nickl kernel: [1128007.749755] ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
Dec 29 00:01:01 nickl kernel: [1128016.857337] b43-phy0 ERROR: PHY transmission error
Dec 29 00:02:08 nickl kernel: [1128083.486959] device wlan0 entered promiscuous mode
Dec 29 00:02:14 nickl kernel: [1128089.096688] b43-phy0 ERROR: PHY transmission error
Dec 29 00:02:26 nickl kernel: [1128101.280579] b43-phy0 ERROR: PHY transmission error


Nick
-- 
Serendipity: http://www.leverton.org/blosxom (last update 29th March 2010)
        "The Internet, a sort of ersatz counterfeit of real life"
                -- Janet Street-Porter, BBC2, 19th March 1996


^ permalink raw reply

* Re: 2.6.37-rc7: Regression: b43: crashes in hwrng_register()
From: Larry Finger @ 2010-12-29  0:34 UTC (permalink / raw)
  To: Mario Holbe; +Cc: LKML, wireless, b43-dev

Mario Holbe wrote:

> on 2.6.37-rc7 the b43 driver crashes in hwrng_register(). This makes the
> system virtually unusable since it appears to block networking syscalls.
> This leads to, for example, ifconfig never return.
> This issue does also exist in 2.6.37-rc5.
> This issue does not exist in 2.6.36.2.
>
> The hardware in question is:
> 02:00.0 Network controller [0280]: Broadcom Corporation BCM4312 802.11b/g
LP-PHY [14e4:4315] (rev 01)
> on a Lenovo Ideapad S12 with VIA Nano.

> dmesg excerpt:
> [ 2.056847] b43-pci-bridge 0000:02:00.0: PCI INT A -> GSI 28 (level, low) ->
IRQ 28
> [ 2.056864] b43-pci-bridge 0000:02:00.0: setting latency timer to 64
...
> [ 8.643695] b43-phy0: Broadcom 4312 WLAN found (core revision 15)
> [ 9.047514] ieee80211 phy0: Selected rate control algorithm 'minstrel_ht'
> [ 9.048441] Registered led device: b43-phy0::tx
> [ 9.048479] Registered led device: b43-phy0::rx
> [ 9.048518] Registered led device: b43-phy0::radio
> [ 9.048542] Broadcom 43xx driver loaded [ Features: PMLS, Firmware-ID: FW13 ]
...
> [ 24.312100] b43-phy0: Loading firmware version 410.2160 (2007-05-26 15:32:10)
...
> [ 29.848400] b43-pci-bridge 0000:02:00.0: PCI: Disallowing DAC for device
> [ 29.848407] b43-phy0: DMA mask fallback from 64-bit to 32-bit
> [ 29.868632] BUG: unable to handle kernel paging request at 907cde0c
> [ 29.868640] IP: [<f8d543cc>] hwrng_register+0x4c/0x139 [rng_core]
> [ 29.868655] *pde = 00000000
> [ 29.868659] Oops: 0000 [#1] SMP
> [ 29.868664] last sysfs file: /sys/bus/pci/drivers/parport_pc/uevent
> [ 29.868670] Modules linked in: parport_pc ppdev lp parport sbs sbshc
power_meter pci_slot hed fan container acpi_cpufreq mperf cpufreq_conservative
cpufreq_userspace cpufreq_stats cpufreq_powersave dm_crypt fuse loop eeprom
via_cputemp i2c_dev nvram padlock_aes aes_i586 aes_generic padlock_sha
sha256_generic sha1_generic via_rng msr cpuid snd_hda_codec_realtek
snd_hda_intel snd_hda_codec arc4 snd_hwdep ecb snd_pcm_oss snd_mixer_oss snd_pcm
snd_seq_midi b43 snd_rawmidi uvcvideo snd_seq_midi_event joydev videodev btusb
snd_seq rng_core video ac battery tpm_tis v4l1_compat tpm tpm_bios output
power_supply i2c_viapro snd_timer ideapad_laptop snd_seq_device serio_raw wmi
mac80211 cfg80211 processor snd pcspkr i2c_core psmouse button bluetooth evdev
shpchp soundcore snd_page_alloc rfkill pci_hotplug ext3 jbd mbcache raid10
raid456 async_raid6_recov async_pq raid6_pq async_xor xor async_memcpy async_tx
raid1 raid0 multipath linear md_mod dm_mirror dm_region_hash dm_log dm_mod btrfs zli
b_deflate crc32c libcrc32c sd_mod crc_t10dif ata_generic uhci_hcd pata_via
libata ssb ehci_hcd tg3 scsi_mod usbcore pcmcia via_sdmmc mmc_core pcmcia_core
libphy thermal thermal_sys nls_base [last unloaded: scsi_wait_scan]
> [ 29.868810]
> [ 29.868816] Pid: 1781, comm: NetworkManager Not tainted 2.6.37-rc7-686 #1
MoutCook/20021,2959
> [ 29.868822] EIP: 0060:[<f8d543cc>] EFLAGS: 00010286 CPU: 0
> [ 29.868829] EIP is at hwrng_register+0x4c/0x139 [rng_core]
> [ 29.868834] EAX: 00000001 EBX: f4b17010 ECX: f6e5db6c EDX: f4b17035
> [ 29.868839] ESI: 907cddf0 EDI: 00000000 EBP: 00000036 ESP: f6e5db54
> [ 29.868844] DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
> [ 29.868850] Process NetworkManager (pid: 1781, ti=f6e5c000 task=f6eb6080
task.ti=f6e5c000)
> [ 29.868854] Stack:
> [ 29.868856] f4b16fc0 f4b17035 f8e5a870 f4b17035 0000001f f8e70095 f8e6f9ca
f4b71e70
> [ 29.868866] 0000000f f6c95000 f6c95000 f6e97400 f4b162c0 f4b10240 f4b16fc8
f8e5ad67
> [ 29.868875] f89e43da f4b162c0 f6cab400 f8b80e44 f6cab000 f8b70889 f8b6fe7a
00000000
> [ 29.868884] Call Trace:
> [ 29.868909] [<f8e5a870>] ? b43_wireless_core_init+0xd0c/0xdd6 [b43]
> [ 29.868925] [<f8e5ad67>] ? b43_op_start+0xf8/0x142 [b43]
> [ 29.868947] [<f89e43da>] ? cfg80211_netdev_notifier_call+0x342/0x355 [cfg80211]
> [ 29.868984] [<f8b70889>] ? ieee80211_do_open+0xed/0x45f [mac80211]
> [ 29.869002] [<f8b6fe7a>] ? ieee80211_check_concurrent_iface+0x1c/0x135 [mac80211]
> [ 29.869015] [<c11edcba>] ? __dev_open+0x7d/0xa7
> [ 29.869022] [<c11ec683>] ? __dev_change_flags+0x9a/0x10d
> [ 29.869028] [<c11edc12>] ? dev_change_flags+0x10/0x3b
> [ 29.869036] [<c11f7c77>] ? do_setlink+0x23e/0x532
> [ 29.869044] [<c11f803b>] ? rtnl_setlink+0xd0/0xe1
> [ 29.869058] [<c1145b00>] ? __strncpy_from_user+0x1d/0x2b
> [ 29.869064] [<c11f7f6b>] ? rtnl_setlink+0x0/0xe1
> [ 29.869069] [<c11f77a2>] ? rtnetlink_rcv_msg+0x186/0x19c
> [ 29.869075] [<c11f761c>] ? rtnetlink_rcv_msg+0x0/0x19c
> [ 29.869082] [<c1206818>] ? netlink_rcv_skb+0x2d/0x72
> [ 29.869088] [<c11f7616>] ? rtnetlink_rcv+0x18/0x1e
> [ 29.869093] [<c120666c>] ? netlink_unicast+0xba/0x10e
> [ 29.869099] [<c1207170>] ? netlink_sendmsg+0x23d/0x256
> [ 29.869111] [<c11dfe26>] ? __sock_sendmsg+0x48/0x4e
> [ 29.869117] [<c11e008f>] ? sock_sendmsg+0x78/0x8f
> [ 29.869123] [<c11e008f>] ? sock_sendmsg+0x78/0x8f
> [ 29.869131] [<c10c6785>] ? d_kill+0x38/0x3d
> [ 29.869141] [<c11e7f0c>] ? verify_iovec+0x3d/0x79
> [ 29.869147] [<c11e088d>] ? sys_sendmsg+0x15f/0x1c1
> [ 29.869153] [<c11e04c4>] ? sockfd_lookup_light+0x13/0x3f
> [ 29.869160] [<c11e0b25>] ? sys_sendto+0xfd/0x121
> [ 29.869166] [<c11e43eb>] ? sk_prot_alloc+0x62/0xd6
> [ 29.869174] [<c1001e6e>] ? __switch_to+0x6f/0xe2
> [ 29.869183] [<c12860de>] ? schedule+0x579/0x5b6
> [ 29.869190] [<c11e0723>] ? sys_recvmsg+0x3c/0x47
> [ 29.869196] [<c11e1afd>] ? sys_socketcall+0x17f/0x1cb
> [ 29.869202] [<c1002f9f>] ? sysenter_do_call+0x12/0x28
> [ 29.869206] Code: f8 e8 46 25 53 c8 8b 35 ec 45 d5 f8 eb 1a 8b 13 8b 06 e8 17
11 3f c8 85 c0 75 0a be ef ff ff ff e9 d3 00 00 00 8b 76 1c 83 ee 1c <8b> 46 1c
0f 18 00 90 81 fe d0 45 d5 f8 75 d4 83 3d ec 47 d5 f8
> [ 29.869249] EIP: [<f8d543cc>] hwrng_register+0x4c/0x139 [rng_core] SS:ESP
0068:f6e5db54
> [ 29.869259] CR2: 00000000907cde0c
> [ 29.869264] ---[ end trace 6719399ed79e8cc1 ]---

I almost missed this posting. Please post wireless problems with
linux-wireless@vger.kernel.org for better visibility.

I have a BCM4312 (14e4:4315) on a netbook that does not have this problem, thus
I will have to rely on your debugging. An additional difficulty is that the only
changes to b43 between 2.6.36 and 2.6.37 are adding an additional PCI ID, some
fixes to the SDIO driver, and some code for an 802.11n device. None of these
should affect your 802.11 b/g unit.

Is it possible for you to bisect between 2.6.36 and 2.6.37-rc5? I wish I could
suggest some way to minimize the number of commits and builds, but the problem
could be anywhere.

Larry

^ permalink raw reply

* Re: [PATCH 2/3] carl9170: reduce channel change delay
From: Felix @ 2010-12-29  0:39 UTC (permalink / raw)
  To: Christian Lamparter; +Cc: linux-wireless, linville
In-Reply-To: <E1PWwiD-0003TF-Qt@debian64.daheim>

Hi Christian,

in 2006 people didn't worry about bg-scan yet, so this stuff didn't get
optimized. Make it look like ath9k for ar9001. Btw I deeply appreciate
your work.

Best regards, Felix

On Sun, 2010-12-26 at 18:22 +0100, Christian Lamparter wrote:
> By removing two "safety" msleeps (and an echo nop), the
> channel change delay is effectively halved. Previously,
> the delay could be as long as 260 ms and the device
> could not go off-channel without risking to miss the
> next DTIM beacon [interval ~307 ms].
> 
> Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
> ---
> Hi Felix,
> 
> It seems that removing the msleeps doesn't have ANY negative effect
> on the operation. Furthermore ath9k doesn't need the 20ms+ msleeps
> in the phy codepaths either. So, I wonder if this is just some old
> "safety" buffers which survived otus and ar9170usb development
> phases, or is there some merit to them?
> 
> Regards,
> 	Chr
> ---
>  drivers/net/wireless/ath/carl9170/phy.c |    8 --------
>  1 files changed, 0 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c
> index 122e75e..b6b0de6 100644
> --- a/drivers/net/wireless/ath/carl9170/phy.c
> +++ b/drivers/net/wireless/ath/carl9170/phy.c
> @@ -1029,8 +1029,6 @@ static int carl9170_init_rf_bank4_pwr(struct ar9170 *ar, bool band5ghz,
>  	if (err)
>  		return err;
>  
> -	msleep(20);
> -
>  	return 0;
>  }
>  
> @@ -1660,12 +1658,6 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
>  			return err;
>  
>  		cmd = CARL9170_CMD_RF_INIT;
> -
> -		msleep(100);
> -
> -		err = carl9170_echo_test(ar, 0xaabbccdd);
> -		if (err)
> -			return err;
>  	} else {
>  		cmd = CARL9170_CMD_FREQUENCY;
>  	}



^ permalink raw reply

* [PATCH 4/4] mwl8k: Enable HW encryption for AP mode
From: Thomas Pedersen @ 2010-12-28 23:01 UTC (permalink / raw)
  To: linux-wireless
  Cc: mwl8k-devel, buytenh, Nishant Sarmukadam, Pradeep Nemavat,
	Thomas Pedersen
In-Reply-To: <1293577297-25755-1-git-send-email-thomas@cozybit.com>

From: Nishant Sarmukadam <nishants@marvell.com>

set_key callback is defined for mac80211 to install keys for HW crypto in AP
mode. Driver currently falls back to SW crypto in STA mode.  Add support to
configure the keys appropriately in the hardware after the set_key routine is
called.

Signed-off-by: Nishant Sarmukadam <nishants@marvell.com>
Signed-off-by: Pradeep Nemavat <pnemavat@marvell.com>
Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
---
 drivers/net/wireless/mwl8k.c |  300 ++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 290 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 75200d5..046ddfd 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -267,6 +267,7 @@ struct mwl8k_vif {
 	bool is_hw_crypto_enabled;
 };
 #define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv))
+#define IEEE80211_KEY_CONF(_u8) ((struct ieee80211_key_conf *)(_u8))
 
 struct mwl8k_sta {
 	/* Index into station database. Returned by UPDATE_STADB.  */
@@ -362,6 +363,7 @@ static const struct ieee80211_rate mwl8k_rates_50[] = {
 #define MWL8K_CMD_SET_RATEADAPT_MODE	0x0203
 #define MWL8K_CMD_BSS_START		0x1100		/* per-vif */
 #define MWL8K_CMD_SET_NEW_STN		0x1111		/* per-vif */
+#define MWL8K_CMD_UPDATE_ENCRYPTION	0x1122		/* per-vif */
 #define MWL8K_CMD_UPDATE_STADB		0x1123
 
 static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize)
@@ -400,6 +402,7 @@ static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize)
 		MWL8K_CMDNAME(SET_RATEADAPT_MODE);
 		MWL8K_CMDNAME(BSS_START);
 		MWL8K_CMDNAME(SET_NEW_STN);
+		MWL8K_CMDNAME(UPDATE_ENCRYPTION);
 		MWL8K_CMDNAME(UPDATE_STADB);
 	default:
 		snprintf(buf, bufsize, "0x%x", cmd);
@@ -824,15 +827,22 @@ static void mwl8k_encapsulate_tx_frame(struct sk_buff *skb)
 	header_pad = 0;
 	data_pad = 0;
 	if (key_conf != NULL) {
-		if (key_conf->alg == ALG_WEP) {
+		switch (key_conf->cipher) {
+		case WLAN_CIPHER_SUITE_WEP40:
+		case WLAN_CIPHER_SUITE_WEP104:
 			header_pad = 4;
 			data_pad = 4;
-		} else {
+			break;
+		case WLAN_CIPHER_SUITE_TKIP:
 			header_pad = 8;
-			if (key_conf->alg == ALG_TKIP)
-				data_pad = 12;
-			else /* CCMP */
-				data_pad = 8;
+			data_pad = 12;
+			break;
+		case WLAN_CIPHER_SUITE_CCMP:
+			header_pad = 8;
+			data_pad = 8;
+			break;
+		default:
+			return -ENOTSUPP;
 		}
 	}
 
@@ -843,7 +853,7 @@ static void mwl8k_encapsulate_tx_frame(struct sk_buff *skb)
 	/*
 	 * Fill CCMP header.
 	 */
-	if ((key_conf != NULL) && key_conf->alg == ALG_CCMP) {
+	if (key_conf != NULL && key_conf->cipher == WLAN_CIPHER_SUITE_CCMP) {
 		void *ccmp_hdr;
 		u8 key_id;
 		struct mwl8k_ccmp_tx_iv *tx_iv;
@@ -3291,6 +3301,273 @@ static int mwl8k_cmd_set_new_stn_del(struct ieee80211_hw *hw,
 }
 
 /*
+ * CMD_UPDATE_ENCRYPTION.
+ */
+
+#define MAX_ENCR_KEY_LENGTH	16
+#define MIC_KEY_LENGTH		8
+
+struct mwl8k_cmd_update_encryption {
+	struct mwl8k_cmd_pkt header;
+
+	__le32 action;
+	__le32 reserved;
+	__u8 mac_addr[6];
+	__u8 encr_type;
+
+} __attribute__((packed));
+
+struct mwl8k_cmd_set_key {
+	struct mwl8k_cmd_pkt header;
+
+	__le32 action;
+	__le32 reserved;
+	__le16 length;
+	__le16 key_type_id;
+	__le32 key_info;
+	__le32 key_id;
+	__le16 key_len;
+	__u8 key_material[MAX_ENCR_KEY_LENGTH];
+	__u8 tkip_tx_mic_key[MIC_KEY_LENGTH];
+	__u8 tkip_rx_mic_key[MIC_KEY_LENGTH];
+	__le16 tkip_rsc_low;
+	__le32 tkip_rsc_high;
+	__le16 tkip_tsc_low;
+	__le32 tkip_tsc_high;
+	__u8 mac_addr[6];
+} __attribute__((packed));
+
+enum {
+	MWL8K_ENCR_ENABLE,
+	MWL8K_ENCR_SET_KEY,
+	MWL8K_ENCR_REMOVE_KEY,
+	MWL8K_ENCR_SET_GROUP_KEY,
+};
+
+#define MWL8K_UPDATE_ENCRYPTION_TYPE_WEP	0
+#define MWL8K_UPDATE_ENCRYPTION_TYPE_DISABLE	1
+#define MWL8K_UPDATE_ENCRYPTION_TYPE_TKIP	4
+#define MWL8K_UPDATE_ENCRYPTION_TYPE_MIXED	7
+#define MWL8K_UPDATE_ENCRYPTION_TYPE_AES	8
+
+enum {
+	MWL8K_ALG_WEP,
+	MWL8K_ALG_TKIP,
+	MWL8K_ALG_CCMP,
+};
+
+#define MWL8K_KEY_FLAG_TXGROUPKEY	0x00000004
+#define MWL8K_KEY_FLAG_PAIRWISE		0x00000008
+#define MWL8K_KEY_FLAG_TSC_VALID	0x00000040
+#define MWL8K_KEY_FLAG_WEP_TXKEY	0x01000000
+#define MWL8K_KEY_FLAG_MICKEY_VALID	0x02000000
+
+static int mwl8k_cmd_update_encryption_enable(struct ieee80211_hw *hw,
+					      struct ieee80211_vif *vif,
+					      u8 *addr,
+					      u8 encr_type)
+{
+	struct mwl8k_cmd_update_encryption *cmd;
+	int rc;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_ENCRYPTION);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+	cmd->action = cpu_to_le32(MWL8K_ENCR_ENABLE);
+	memcpy(cmd->mac_addr, addr, ETH_ALEN);
+	cmd->encr_type = encr_type;
+
+	rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
+	kfree(cmd);
+
+	return rc;
+}
+
+static int mwl8k_encryption_set_cmd_info(struct mwl8k_cmd_set_key *cmd,
+						u8 *addr,
+						struct ieee80211_key_conf *key)
+{
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_ENCRYPTION);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+	cmd->length = cpu_to_le16(sizeof(*cmd) -
+				offsetof(struct mwl8k_cmd_set_key, length));
+	cmd->key_id = cpu_to_le32(key->keyidx);
+	cmd->key_len = cpu_to_le16(key->keylen);
+	memcpy(cmd->mac_addr, addr, ETH_ALEN);
+
+	switch (key->cipher) {
+	case WLAN_CIPHER_SUITE_WEP40:
+	case WLAN_CIPHER_SUITE_WEP104:
+		cmd->key_type_id = cpu_to_le16(MWL8K_ALG_WEP);
+		if (key->keyidx == 0)
+			cmd->key_info =	cpu_to_le32(MWL8K_KEY_FLAG_WEP_TXKEY);
+
+		break;
+	case WLAN_CIPHER_SUITE_TKIP:
+		cmd->key_type_id = cpu_to_le16(MWL8K_ALG_TKIP);
+		cmd->key_info =	(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
+			? cpu_to_le32(MWL8K_KEY_FLAG_PAIRWISE)
+			: cpu_to_le32(MWL8K_KEY_FLAG_TXGROUPKEY);
+		cmd->key_info |= cpu_to_le32(MWL8K_KEY_FLAG_MICKEY_VALID
+						| MWL8K_KEY_FLAG_TSC_VALID);
+		break;
+	case WLAN_CIPHER_SUITE_CCMP:
+		cmd->key_type_id = cpu_to_le16(MWL8K_ALG_CCMP);
+		cmd->key_info =	(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
+			? cpu_to_le32(MWL8K_KEY_FLAG_PAIRWISE)
+			: cpu_to_le32(MWL8K_KEY_FLAG_TXGROUPKEY);
+		break;
+	default:
+		return -ENOTSUPP;
+	}
+
+	return 0;
+}
+
+static int mwl8k_cmd_encryption_set_key(struct ieee80211_hw *hw,
+						struct ieee80211_vif *vif,
+						u8 *addr,
+						struct ieee80211_key_conf *key)
+{
+	struct mwl8k_cmd_set_key *cmd;
+	int rc;
+	int keymlen;
+	u32 action;
+	u8 idx;
+	struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	rc = mwl8k_encryption_set_cmd_info(cmd, addr, key);
+	if (rc < 0)
+		goto done;
+
+	idx = key->keyidx;
+
+	if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
+		action = MWL8K_ENCR_SET_KEY;
+	else
+		action = MWL8K_ENCR_SET_GROUP_KEY;
+
+	switch (key->cipher) {
+	case WLAN_CIPHER_SUITE_WEP40:
+	case WLAN_CIPHER_SUITE_WEP104:
+		if (!mwl8k_vif->wep_key_conf[idx].enabled) {
+			memcpy(mwl8k_vif->wep_key_conf[idx].key, key,
+						sizeof(*key) + key->keylen);
+			mwl8k_vif->wep_key_conf[idx].enabled = 1;
+		}
+
+		keymlen = 0;
+		action = MWL8K_ENCR_SET_KEY;
+		break;
+	case WLAN_CIPHER_SUITE_TKIP:
+		keymlen = MAX_ENCR_KEY_LENGTH + 2 * MIC_KEY_LENGTH;
+		break;
+	case WLAN_CIPHER_SUITE_CCMP:
+		keymlen = key->keylen;
+		break;
+	default:
+		rc = -ENOTSUPP;
+		goto done;
+	}
+
+	memcpy(cmd->key_material, key->key, keymlen);
+	cmd->action = cpu_to_le32(action);
+
+	rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
+done:
+	kfree(cmd);
+
+	return rc;
+}
+
+static int mwl8k_cmd_encryption_remove_key(struct ieee80211_hw *hw,
+						struct ieee80211_vif *vif,
+						u8 *addr,
+						struct ieee80211_key_conf *key)
+{
+	struct mwl8k_cmd_set_key *cmd;
+	int rc;
+	struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	rc = mwl8k_encryption_set_cmd_info(cmd, addr, key);
+	if (rc < 0)
+		goto done;
+
+	if (key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
+			WLAN_CIPHER_SUITE_WEP104)
+		mwl8k_vif->wep_key_conf[key->keyidx].enabled = 0;
+
+	cmd->action = cpu_to_le32(MWL8K_ENCR_REMOVE_KEY);
+
+	rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
+done:
+	kfree(cmd);
+
+	return rc;
+}
+
+static int mwl8k_set_key(struct ieee80211_hw *hw,
+			 enum set_key_cmd cmd_param,
+			 struct ieee80211_vif *vif,
+			 struct ieee80211_sta *sta,
+			 struct ieee80211_key_conf *key)
+{
+	int rc = 0;
+	u8 encr_type;
+	u8 *addr;
+	struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
+
+	if (vif->type == NL80211_IFTYPE_STATION)
+		return -EOPNOTSUPP;
+
+	if (sta == NULL)
+		addr = hw->wiphy->perm_addr;
+	else
+		addr = sta->addr;
+
+	if (cmd_param == SET_KEY) {
+		rc = mwl8k_cmd_encryption_set_key(hw, vif, addr, key);
+		if (rc)
+			goto out;
+
+		if ((key->cipher == WLAN_CIPHER_SUITE_WEP40)
+				|| (key->cipher == WLAN_CIPHER_SUITE_WEP104))
+			encr_type = MWL8K_UPDATE_ENCRYPTION_TYPE_WEP;
+		else
+			encr_type = MWL8K_UPDATE_ENCRYPTION_TYPE_MIXED;
+
+		rc = mwl8k_cmd_update_encryption_enable(hw, vif, addr,
+								encr_type);
+		if (rc)
+			goto out;
+
+		mwl8k_vif->is_hw_crypto_enabled = true;
+
+	} else {
+		rc = mwl8k_cmd_encryption_remove_key(hw, vif, addr, key);
+
+		if (rc)
+			goto out;
+
+		mwl8k_vif->is_hw_crypto_enabled = false;
+
+	}
+out:
+	return rc;
+}
+
+/*
  * CMD_UPDATE_STADB.
  */
 struct ewc_ht_info {
@@ -4062,6 +4339,9 @@ static int mwl8k_sta_add(struct ieee80211_hw *hw,
 {
 	struct mwl8k_priv *priv = hw->priv;
 	int ret;
+	int i;
+	struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
+	struct ieee80211_key_conf *key;
 
 	MWL8K_STA(sta)->ccmp_tx_iv.tx_iv_pn_l2 = 1;
 	MWL8K_STA(sta)->ccmp_tx_iv.tx_iv_pn_u4 = 0;
@@ -4070,12 +4350,11 @@ static int mwl8k_sta_add(struct ieee80211_hw *hw,
 		ret = mwl8k_cmd_update_stadb_add(hw, vif, sta);
 		if (ret >= 0) {
 			MWL8K_STA(sta)->peer_id = ret;
-			return 0;
+			ret = 0;
 		}
 
 	} else {
 		ret = mwl8k_cmd_set_new_stn_add(hw, vif, sta);
-		return ret;
 	}
 
 	for (i = 0; i < NUM_WEP_KEYS; i++) {
@@ -4083,7 +4362,7 @@ static int mwl8k_sta_add(struct ieee80211_hw *hw,
 		if (mwl8k_vif->wep_key_conf[i].enabled)
 			mwl8k_set_key(hw, SET_KEY, vif, sta, key);
 	}
-	return mwl8k_cmd_set_new_stn_add(hw, vif, sta);
+	return ret;
 }
 
 static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue,
@@ -4161,6 +4440,7 @@ static const struct ieee80211_ops mwl8k_ops = {
 	.bss_info_changed	= mwl8k_bss_info_changed,
 	.prepare_multicast	= mwl8k_prepare_multicast,
 	.configure_filter	= mwl8k_configure_filter,
+	.set_key                = mwl8k_set_key,
 	.set_rts_threshold	= mwl8k_set_rts_threshold,
 	.sta_add		= mwl8k_sta_add,
 	.sta_remove		= mwl8k_sta_remove,
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 3/4] mwl8k: Set mac80211 rx status flags appropriately when hw crypto is enabled
From: Thomas Pedersen @ 2010-12-28 23:01 UTC (permalink / raw)
  To: linux-wireless
  Cc: mwl8k-devel, buytenh, Nishant Sarmukadam, yogesh powar,
	Thomas Pedersen
In-Reply-To: <1293577297-25755-1-git-send-email-thomas@cozybit.com>

From: Nishant Sarmukadam <nishants@marvell.com>

When hw crypto is enabled, set rx status flags appropriately depending on
whether hw crypto is enabled for a particular bss.
Also report MIC errors to mac80211, so that counter measures can be
initiated

Signed-off-by: Nishant Sarmukadam <nishants@marvell.com>
Signed-off-by: yogesh powar <yogeshp@marvell.com>
Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
---
 drivers/net/wireless/mwl8k.c |  100 ++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 97 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 508828c..75200d5 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -259,6 +259,12 @@ struct mwl8k_vif {
 
 	/* CCMP Crypto counters for Group cast data */
 	struct mwl8k_ccmp_tx_iv ccmp_tx_iv;
+
+	/* BSSID */
+	u8 bssid[ETH_ALEN];
+
+	/* A flag to indicate is HW crypto is enabled for this bssid */
+	bool is_hw_crypto_enabled;
 };
 #define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv))
 
@@ -885,6 +891,13 @@ struct mwl8k_rxd_8366_ap {
 
 #define MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST	0x80
 
+/* 8366 AP rx_status bits */
+#define MWL8K_8366_AP_RXSTAT_DECRYPT_ERR_MASK		0x80
+#define MWL8K_8366_AP_RXSTAT_GENERAL_DECRYPT_ERR	0xFF
+#define MWL8K_8366_AP_RXSTAT_TKIP_DECRYPT_MIC_ERR	0x02
+#define MWL8K_8366_AP_RXSTAT_WEP_DECRYPT_ICV_ERR	0x04
+#define MWL8K_8366_AP_RXSTAT_TKIP_DECRYPT_ICV_ERR	0x08
+
 static void mwl8k_rxd_8366_ap_init(void *_rxd, dma_addr_t next_dma_addr)
 {
 	struct mwl8k_rxd_8366_ap *rxd = _rxd;
@@ -945,6 +958,11 @@ mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status,
 
 	*qos = rxd->qos_control;
 
+	if ((rxd->rx_status != MWL8K_8366_AP_RXSTAT_GENERAL_DECRYPT_ERR) &&
+		(rxd->rx_status & MWL8K_8366_AP_RXSTAT_DECRYPT_ERR_MASK) &&
+		(rxd->rx_status & MWL8K_8366_AP_RXSTAT_TKIP_DECRYPT_MIC_ERR))
+			status->flag |= RX_FLAG_MMIC_ERROR;
+
 	return le16_to_cpu(rxd->pkt_len);
 }
 
@@ -983,6 +1001,11 @@ struct mwl8k_rxd_sta {
 #define MWL8K_STA_RATE_INFO_MCS_FORMAT		0x0001
 
 #define MWL8K_STA_RX_CTRL_OWNED_BY_HOST		0x02
+#define MWL8K_STA_RX_CTRL_DECRYPT_ERROR		0x04
+/* ICV=0 or MIC=1 */
+#define MWL8K_STA_RX_CTRL_DEC_ERR_TYPE		0x08
+/* Key is uploaded only in failure case */
+#define MWL8K_STA_RX_CTRL_KEY_INDEX			0x30
 
 static void mwl8k_rxd_sta_init(void *_rxd, dma_addr_t next_dma_addr)
 {
@@ -1041,6 +1064,9 @@ mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status,
 	status->freq = ieee80211_channel_to_frequency(rxd->channel);
 
 	*qos = rxd->qos_control;
+	if ((rxd->rx_ctrl & MWL8K_STA_RX_CTRL_DECRYPT_ERROR) &&
+			(rxd->rx_ctrl & MWL8K_STA_RX_CTRL_DEC_ERR_TYPE))
+				status->flag |= RX_FLAG_MMIC_ERROR;
 
 	return le16_to_cpu(rxd->pkt_len);
 }
@@ -1199,9 +1225,24 @@ static inline void mwl8k_save_beacon(struct ieee80211_hw *hw,
 		ieee80211_queue_work(hw, &priv->finalize_join_worker);
 }
 
+struct mwl8k_vif *mwl8k_find_vif_bss(struct list_head *vif_list, u8 *bssid)
+{
+	struct mwl8k_vif *mwl8k_vif;
+
+	list_for_each_entry(mwl8k_vif,
+			vif_list, list) {
+		if (memcmp(bssid, mwl8k_vif->bssid,
+				 ETH_ALEN) == 0)
+			return mwl8k_vif;
+	}
+
+	return NULL;
+}
+
 static int rxq_process(struct ieee80211_hw *hw, int index, int limit)
 {
 	struct mwl8k_priv *priv = hw->priv;
+	struct mwl8k_vif *mwl8k_vif = NULL;
 	struct mwl8k_rx_queue *rxq = priv->rxq + index;
 	int processed;
 
@@ -1211,6 +1252,7 @@ static int rxq_process(struct ieee80211_hw *hw, int index, int limit)
 		void *rxd;
 		int pkt_len;
 		struct ieee80211_rx_status status;
+		struct ieee80211_hdr *wh;
 		__le16 qos;
 
 		skb = rxq->buf[rxq->head].skb;
@@ -1237,8 +1279,7 @@ static int rxq_process(struct ieee80211_hw *hw, int index, int limit)
 
 		rxq->rxd_count--;
 
-		skb_put(skb, pkt_len);
-		mwl8k_remove_dma_header(skb, qos);
+		wh = &((struct mwl8k_dma_data *)skb->data)->wh;
 
 		/*
 		 * Check for a pending join operation.  Save a
@@ -1248,6 +1289,46 @@ static int rxq_process(struct ieee80211_hw *hw, int index, int limit)
 		if (mwl8k_capture_bssid(priv, (void *)skb->data))
 			mwl8k_save_beacon(hw, skb);
 
+		if (ieee80211_has_protected(wh->frame_control)) {
+
+			/* Check if hw crypto has been enabled for
+			 * this bss. If yes, set the status flags
+			 * accordingly
+			 */
+			mwl8k_vif = mwl8k_find_vif_bss(&priv->vif_list,
+								wh->addr1);
+
+			if (mwl8k_vif != NULL &&
+				mwl8k_vif->is_hw_crypto_enabled == true) {
+				/*
+				 * When MMIC ERROR is encountered
+				 * by the firmware, payload is
+				 * dropped and only 32 bytes of
+				 * mwl8k Firmware header is sent
+				 * to the host.
+				 *
+				 * We need to add four bytes of
+				 * key information.  In it
+				 * MAC80211 expects keyidx set to
+				 * 0 for triggering Counter
+				 * Measure of MMIC failure.
+				 */
+				if (status.flag & RX_FLAG_MMIC_ERROR) {
+					struct mwl8k_dma_data *tr;
+					tr = (struct mwl8k_dma_data *)skb->data;
+					memset((void *)&(tr->data), 0, 4);
+					pkt_len += 4;
+				}
+
+				if (!ieee80211_is_auth(wh->frame_control))
+					status.flag |= RX_FLAG_IV_STRIPPED |
+							RX_FLAG_DECRYPTED |
+							RX_FLAG_MMIC_STRIPPED;
+			}
+		}
+
+		skb_put(skb, pkt_len);
+		mwl8k_remove_dma_header(skb, qos);
 		memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
 		ieee80211_rx_irqsafe(hw, skb);
 
@@ -1550,7 +1631,11 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
 	else
 		qos = 0;
 
-	mwl8k_encapsulate_tx_frame(skb);
+	if (priv->ap_fw)
+		mwl8k_encapsulate_tx_frame(skb);
+	else
+		mwl8k_add_dma_header(skb, 0, 0);
+
 	wh = &((struct mwl8k_dma_data *)skb->data)->wh;
 
 	tx_info = IEEE80211_SKB_CB(skb);
@@ -3578,6 +3663,8 @@ static int mwl8k_add_interface(struct ieee80211_hw *hw,
 	mwl8k_vif->seqno = 0;
 	mwl8k_vif->ccmp_tx_iv.tx_iv_pn_l2 = 1;
 	mwl8k_vif->ccmp_tx_iv.tx_iv_pn_u4 = 0;
+	memcpy(mwl8k_vif->bssid, vif->addr, ETH_ALEN);
+	mwl8k_vif->is_hw_crypto_enabled = false;
 
 	/* Set the mac address.  */
 	mwl8k_cmd_set_mac_addr(hw, vif, vif->addr);
@@ -3986,9 +4073,16 @@ static int mwl8k_sta_add(struct ieee80211_hw *hw,
 			return 0;
 		}
 
+	} else {
+		ret = mwl8k_cmd_set_new_stn_add(hw, vif, sta);
 		return ret;
 	}
 
+	for (i = 0; i < NUM_WEP_KEYS; i++) {
+		key = IEEE80211_KEY_CONF(mwl8k_vif->wep_key_conf[i].key);
+		if (mwl8k_vif->wep_key_conf[i].enabled)
+			mwl8k_set_key(hw, SET_KEY, vif, sta, key);
+	}
 	return mwl8k_cmd_set_new_stn_add(hw, vif, sta);
 }
 
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 2/4] mwl8k: Add encapsulation of data packet for crypto
From: Thomas Pedersen @ 2010-12-28 23:01 UTC (permalink / raw)
  To: linux-wireless
  Cc: mwl8k-devel, buytenh, Nishant Sarmukadam, Pradeep Nemavat,
	Thomas Pedersen
In-Reply-To: <1293577297-25755-1-git-send-email-thomas@cozybit.com>

From: Nishant Sarmukadam <nishants@marvell.com>

Different head and tail pads will be needed for crypto depending on
the crypto mode. Add support to encapsulate the packets with
appropriate pad values. Also, fill the header in case of CCMP.

Signed-off-by: Nishant Sarmukadam <nishants@marvell.com>
Signed-off-by: Pradeep Nemavat <pnemavat@marvell.com>
Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
---
 drivers/net/wireless/mwl8k.c |  114 ++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 109 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 771283b..508828c 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -232,6 +232,14 @@ struct mwl8k_priv {
 	struct completion firmware_loading_complete;
 };
 
+#define MAX_WEP_KEY_LEN         13
+#define NUM_WEP_KEYS            4
+
+struct mwl8k_ccmp_tx_iv {
+	__u16 tx_iv_pn_l2;
+	__u32 tx_iv_pn_u4;
+};
+
 /* Per interface specific private data */
 struct mwl8k_vif {
 	struct list_head list;
@@ -242,12 +250,23 @@ struct mwl8k_vif {
 
 	/* Non AMPDU sequence number assigned by driver.  */
 	u16 seqno;
+
+	/* Saved WEP keys */
+	struct {
+		u8 enabled;
+		u8 key[sizeof(struct ieee80211_key_conf) + MAX_WEP_KEY_LEN];
+	} wep_key_conf[NUM_WEP_KEYS];
+
+	/* CCMP Crypto counters for Group cast data */
+	struct mwl8k_ccmp_tx_iv ccmp_tx_iv;
 };
 #define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv))
 
 struct mwl8k_sta {
 	/* Index into station database. Returned by UPDATE_STADB.  */
 	u8 peer_id;
+	/* CCMP crypto counter for station */
+	struct mwl8k_ccmp_tx_iv ccmp_tx_iv;
 };
 #define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv))
 
@@ -747,17 +766,97 @@ mwl8k_add_dma_header(struct sk_buff *skb, int hdr_pad, int tail_pad)
 		memset(((void *)&tr->wh) + hdrlen, 0,
 					sizeof(tr->wh) + hdr_pad - hdrlen);
 
-	if (tail_pad)
-		skb_put(skb, tail_pad);
-
 	/*
 	 * Firmware length is the length of the fully formed "802.11
 	 * payload".  That is, everything except for the 802.11 header.
 	 * This includes all crypto material including the MIC.
 	 */
-	tr->fwlen = cpu_to_le16(skb->len - sizeof(*tr));
+	tr->fwlen = cpu_to_le16(skb->len - sizeof(*tr) + tail_pad);
+}
+
+#define CCMP_EXT_IV (1<<5)
+
+static void
+fill_ccmp_header(u8 *ccmp_hdr, struct mwl8k_ccmp_tx_iv *tx_iv, u8 key_id)
+{
+	*(__le16 *)ccmp_hdr = cpu_to_le16(tx_iv->tx_iv_pn_l2);
+	ccmp_hdr[2] = 0;
+	ccmp_hdr[3] = CCMP_EXT_IV | key_id << 6;
+	*(__le32 *)&ccmp_hdr[4] = cpu_to_le32(tx_iv->tx_iv_pn_u4);
+
+	tx_iv->tx_iv_pn_l2++;
+	if (tx_iv->tx_iv_pn_l2 == 0)
+		tx_iv->tx_iv_pn_u4++;
 }
 
+static void mwl8k_encapsulate_tx_frame(struct sk_buff *skb)
+{
+	struct ieee80211_hdr *wh;
+	struct ieee80211_tx_info *tx_info;
+	struct ieee80211_key_conf *key_conf;
+	int header_pad;
+	int data_pad;
+
+	wh = (struct ieee80211_hdr *)skb->data;
+
+	tx_info = IEEE80211_SKB_CB(skb);
+
+	key_conf = NULL;
+	if (ieee80211_is_data(wh->frame_control))
+		key_conf = tx_info->control.hw_key;
+
+	/*
+	 * Make sure the packet header is in the DMA header format
+	 * (4-address without QoS), and insert the necessary crypto
+	 * padding between the header and the payload.
+	 *
+	 * We have the following header/trailer padding requirements:
+	 * - WEP: 4 header bytes (IV), 4 trailer bytes (ICV)
+	 * - TKIP: 8 header bytes (IV/EIV), 12 trailer bytes (8 MIC + 4 ICV)
+	 * - CCMP: 8 header bytes (PN/KeyId), 8 trailer bytes (MIC)
+	 */
+	header_pad = 0;
+	data_pad = 0;
+	if (key_conf != NULL) {
+		if (key_conf->alg == ALG_WEP) {
+			header_pad = 4;
+			data_pad = 4;
+		} else {
+			header_pad = 8;
+			if (key_conf->alg == ALG_TKIP)
+				data_pad = 12;
+			else /* CCMP */
+				data_pad = 8;
+		}
+	}
+
+	mwl8k_add_dma_header(skb, header_pad, data_pad);
+
+	wh = &((struct mwl8k_dma_data *)skb->data)->wh;
+
+	/*
+	 * Fill CCMP header.
+	 */
+	if ((key_conf != NULL) && key_conf->alg == ALG_CCMP) {
+		void *ccmp_hdr;
+		u8 key_id;
+		struct mwl8k_ccmp_tx_iv *tx_iv;
+
+		ccmp_hdr = skb->data + sizeof(struct mwl8k_dma_data);
+		/*
+		 * The key id is 1 for groupcast traffic and 0 for
+		 * unicast/pairwise traffic.
+		 */
+		if (is_multicast_ether_addr(wh->addr1)) {
+			key_id = 1;
+			tx_iv = &(MWL8K_VIF(tx_info->control.vif)->ccmp_tx_iv);
+		} else {
+			key_id = 0;
+			tx_iv = &(MWL8K_STA(tx_info->control.sta)->ccmp_tx_iv);
+		}
+		fill_ccmp_header(ccmp_hdr, tx_iv, key_id);
+	}
+}
 
 /*
  * Packet reception for 88w8366 AP firmware.
@@ -1451,7 +1550,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
 	else
 		qos = 0;
 
-	mwl8k_add_dma_header(skb, 0, 0);
+	mwl8k_encapsulate_tx_frame(skb);
 	wh = &((struct mwl8k_dma_data *)skb->data)->wh;
 
 	tx_info = IEEE80211_SKB_CB(skb);
@@ -3477,6 +3576,8 @@ static int mwl8k_add_interface(struct ieee80211_hw *hw,
 	mwl8k_vif->vif = vif;
 	mwl8k_vif->macid = macid;
 	mwl8k_vif->seqno = 0;
+	mwl8k_vif->ccmp_tx_iv.tx_iv_pn_l2 = 1;
+	mwl8k_vif->ccmp_tx_iv.tx_iv_pn_u4 = 0;
 
 	/* Set the mac address.  */
 	mwl8k_cmd_set_mac_addr(hw, vif, vif->addr);
@@ -3875,6 +3976,9 @@ static int mwl8k_sta_add(struct ieee80211_hw *hw,
 	struct mwl8k_priv *priv = hw->priv;
 	int ret;
 
+	MWL8K_STA(sta)->ccmp_tx_iv.tx_iv_pn_l2 = 1;
+	MWL8K_STA(sta)->ccmp_tx_iv.tx_iv_pn_u4 = 0;
+
 	if (!priv->ap_fw) {
 		ret = mwl8k_cmd_update_stadb_add(hw, vif, sta);
 		if (ret >= 0) {
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 1/4] mwl8k: Modify add_dma_header to include pad parameters
From: Thomas Pedersen @ 2010-12-28 23:01 UTC (permalink / raw)
  To: linux-wireless
  Cc: mwl8k-devel, buytenh, Nishant Sarmukadam, Pradeep Nemavat,
	Thomas Pedersen
In-Reply-To: <1293577297-25755-1-git-send-email-thomas@cozybit.com>

From: Nishant Sarmukadam <nishants@marvell.com>

Add capability to add_dma_header to support padding at head
and tail of the data packet to be transmitted when crypto is
enabled. Padding is required for adding crypto information
in data packets for supporting 802.11 security modes.

Signed-off-by: Nishant Sarmukadam <nishants@marvell.com>
Signed-off-by: Pradeep Nemavat <pnemavat@marvell.com>
Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
---
 drivers/net/wireless/mwl8k.c |   20 ++++++++++++++------
 1 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 9ecf840..771283b 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -715,10 +715,12 @@ static inline void mwl8k_remove_dma_header(struct sk_buff *skb, __le16 qos)
 		skb_pull(skb, sizeof(*tr) - hdrlen);
 }
 
-static inline void mwl8k_add_dma_header(struct sk_buff *skb)
+static void
+mwl8k_add_dma_header(struct sk_buff *skb, int hdr_pad, int tail_pad)
 {
 	struct ieee80211_hdr *wh;
 	int hdrlen;
+	int reqd_hdrlen;
 	struct mwl8k_dma_data *tr;
 
 	/*
@@ -730,8 +732,10 @@ static inline void mwl8k_add_dma_header(struct sk_buff *skb)
 	wh = (struct ieee80211_hdr *)skb->data;
 
 	hdrlen = ieee80211_hdrlen(wh->frame_control);
-	if (hdrlen != sizeof(*tr))
-		skb_push(skb, sizeof(*tr) - hdrlen);
+	reqd_hdrlen = sizeof(*tr) + hdr_pad;
+
+	if (hdrlen != reqd_hdrlen)
+		skb_push(skb, reqd_hdrlen - hdrlen);
 
 	if (ieee80211_is_data_qos(wh->frame_control))
 		hdrlen -= 2;
@@ -739,8 +743,12 @@ static inline void mwl8k_add_dma_header(struct sk_buff *skb)
 	tr = (struct mwl8k_dma_data *)skb->data;
 	if (wh != &tr->wh)
 		memmove(&tr->wh, wh, hdrlen);
-	if (hdrlen != sizeof(tr->wh))
-		memset(((void *)&tr->wh) + hdrlen, 0, sizeof(tr->wh) - hdrlen);
+	if (hdrlen != sizeof(tr->wh) + hdr_pad)
+		memset(((void *)&tr->wh) + hdrlen, 0,
+					sizeof(tr->wh) + hdr_pad - hdrlen);
+
+	if (tail_pad)
+		skb_put(skb, tail_pad);
 
 	/*
 	 * Firmware length is the length of the fully formed "802.11
@@ -1443,7 +1451,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
 	else
 		qos = 0;
 
-	mwl8k_add_dma_header(skb);
+	mwl8k_add_dma_header(skb, 0, 0);
 	wh = &((struct mwl8k_dma_data *)skb->data)->wh;
 
 	tx_info = IEEE80211_SKB_CB(skb);
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 0/4] mwl8k: Add HW crypto support for AP mode
From: Thomas Pedersen @ 2010-12-28 23:01 UTC (permalink / raw)
  To: linux-wireless; +Cc: mwl8k-devel, buytenh

Hello,

These patches add support for HW crypto using the mwl8k driver when AP firmware
is loaded. The driver currently falls back to SW crypto in mac80211 when in STA
mode, but a future patch will address this. Crypto while an AP and STA both
appear to work fine. 

Thomas


^ permalink raw reply

* Re: [linux-pm] subtle pm_runtime_put_sync race and sdio functions
From: Alan Stern @ 2010-12-28 21:46 UTC (permalink / raw)
  To: Ohad Ben-Cohen
  Cc: Rafael J. Wysocki, linux-pm, Johannes Berg, linux-wireless,
	linux-mmc, Ido Yariv, Kevin Hilman
In-Reply-To: <AANLkTim7pGtO=vjKmA_3O74Kwvio124cgoaMeUSB70dW@mail.gmail.com>

On Tue, 28 Dec 2010, Ohad Ben-Cohen wrote:

> On Sun, Dec 26, 2010 at 7:00 PM, Alan Stern <stern@rowland.harvard.edu> wrote:
> > Hmm.  It's a little difficult to untangle the web of dev_pm_ops
> > pointers and other stuff.
> 
> Yeah, SDIO suspend/resume is very different from other subsystems.
> 
> There are several layers of abstractions involved, from the host
> controller driver, to the MMC core code, to the SDIO core code, to
> finally get to the actual SDIO function driver.

Actually that sounds quite a lot like the USB subsystem, except perhaps
for the fact that you have two layers of core code instead of just one.  
The cards are much like USB devices (indivisible for the purposes of
power management) and the functions are much like USB interfaces (bound
to individual drivers but not independently power-managed or
resettable).

> I'll try to explain it below by addressing your questions. If
> something is still unclear, feel free to ask me.
> 
> > There's wl1271_suspend() and wl1271_resume()
> > (which don't do anything)
> 
> It just looks like they don't. In fact, by returning 0,
> wl1271_suspend() is telling the SDIO subsystem that it's OK to power
> down the SDIO function (in general an SDIO card can have several SDIO
> functions, each of which may be driven by a separate SDIO driver). If
> all the SDIO functions agreed, then SDIO core (mmc_sdio_suspend())
> tells MMC core (mmc_suspend_host()) it's OK to power down the card (by
> directly calling mmc_power_off()).

What's the relation between mmc_power_off() and mmc_power_save_host()?  

When you say "power down", which of these routines do you mean?  I get
the feeling that sometimes you mean one and sometimes the other, which
leads to problems in understanding.

Why are there two separate routines?

Does one merely go into a low-power state whereas the other does the 
complete-power-off reset?

If so, which does which?  

What's the reason for not going into the complete-power-off state every
time?

If it is latency, shouldn't the runtime-PM path use the low-latency
routine and the system-sleep path use the high-latency routine?  
Although I can't tell for certain, it seems to be the other way around.

> > Under what circumstances does the MMC/SDIO core call
> > wl1271_sdio_set_power(), and where are those function calls?
> 
> The relations are actually reversed: the MMC/SDIO core never calls
> this function.
> 
> This function is called by the wl1271 driver itself, mostly as a
> response to a request by the mac80211 layer (but also as a response to
> a hardware error), that requires manipulation of the power of the
> card.
> 
> There are a handful of reasons this may happen:
> 
> error recovery:
> 
> wl1271_recovery_work() ->
>     __wl1271_op_remove_interface() ->
>           wl1271_power_off() ->
>                wl1271_sdio_set_power() ->
>                       wl1271_sdio_power_off() ->
>                              pm_runtime_put_sync()
> 
> wlan interface goes down:
> 
> ieee80211_do_stop() ->
>   wl1271_op_remove_interface() ->
>     __wl1271_op_remove_interface() ->
>           ...
> 
> system suspend:
> 
> __ieee80211_suspend ->
>   wl1271_op_remove_interface() ->
>       ...

Okay.  These paths should be interrelated with power management in a 
different way.

It's correct for wl1271_op_remove_interface() to be called in these 
three situations, and it's correct to do a pm_runtime_put_sync().  But 
it's not correct to rely on that to actually change any power levels or 
do a reset.

Instead, wl1271_error_recovery_work() should call either
mmc_suspend_host() or mmc_power_save_host() (whichever one does the
actual power-off reset) directly, after calling wl1271_power_off().  
In fact, you might even want to do a pm_runtime_get_noresume() before
calling wl1271_power_off(), to prevent the PM core from interfering
with the reset.

Similarly, during system suspend mmc_suspend_host() should be 
responsible for doing all the necessary power-down operations.  Runtime 
PM is completely out of the picture at this time.  And this should be 
independent of mac80211 -- in fact, the card should be powered down 
appropriately even if the kernel doesn't have a mac80211 layer.

During wlan-interface-down, it's not necessary to reduce the power
level; it's merely desirable.  That's exactly the sort of thing runtime
PM is meant for.  Hence the existing call to pm_runtime_put_sync() is
sufficient.

> > Is it possible for there to be more than one device connected to the
> > same MMC/SDIO controller?
> 
> Generally yes, host controllers may have several slots, but to the
> MMC/SDIO core, it is presented as each slot is a separate host
> controller (personally I have never seen such hardware, but I did find
> an example for that in the host controller's source folder).

Put it another way:  Suppose an SDIO card has more than one function 
and you need to reset the wl1271 function.  It sounds like there's no 
way to do this without resetting the other functions as well.  What 
happens if another function's driver is busy and can't allow a reset 
just then?

Alan Stern


^ 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