Merge branch 'google-android' into msm-3.0
Merge Google's Android tree into msm-3.0
This consists of the following conflicts and 42 commits:
Conflicts:
drivers/mmc/core/bus.c
drivers/rtc/class.c
drivers/usb/gadget/android.c
Most of the conflicts stem from the changes made to the
local msm-3.0 branch.
commit 1f8c5cecfe44994cd617ba2803f41fb56d53e91c
Author: Heiko Stuebner <heiko@sntech.de>
Date: Wed Feb 1 10:33:01 2012 -0800
Input: evdev - fix variable initialisation
Commit 509f87c5f564 (evdev - do not block waiting for an event if
fd
is nonblock) created a code path were it was possible to use retval
uninitialized.
This could lead to the xorg evdev input driver getting corrupt data
and refusing to work with log messages like
AUO-Pixcir touchscreen: Read error: Success
sg060_keys: Read error: Success
AUO-Pixcir touchscreen: Read error: Success
sg060_keys: Read error: Success
(for drivers auo-pixcir-ts and gpio-keys).
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
drivers/input/evdev.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
commit 4dc43d7079bdae572212368e1d29abea0177c932
Author: Arve Hjønnevåg <arve@android.com>
Date: Fri Oct 17 15:20:55 2008 -0700
Input: evdev - Add ioctl to block suspend while event queue is not empty.
Add an ioctl, EVIOCSSUSPENDBLOCK, to enable a wakelock that will block
suspend while the event queue is not empty. This allows userspace code to
process input events while the device appears to be asleep.
The current code holds the wakelock for up 5 seconds for every input
device and client. This can prevent suspend if sensor with a high data
rate is active, even when that sensor is not capable of waking the
device once it is suspended.
Change-Id: I624d66ef30a0b3abb543685c343382b8419b42b9
Signed-off-by: Arve Hjønnevåg <arve@android.com>
drivers/input/evdev.c | 53 +++++++++++++++++++++++++++++++++++++++++++-----
include/linux/input.h | 3 ++
2 files changed, 50 insertions(+), 6 deletions(-)
commit 7cc846069a8a9116d8c81526c459070eed0e3477
Author: Arve Hjønnevåg <arve@android.com>
Date: Mon Jan 23 17:15:45 2012 -0800
Input: evdev - Don't hold wakelock when no data is available to user-space
If there is no SYN_REPORT event in the buffer the buffer data is invisible
to user-space. The wakelock should not be held in this case.
Change-Id: Idae890ff0da8eb46a2cfce61a95b3a97252551ad
Signed-off-by: Arve Hjønnevåg <arve@android.com>
drivers/input/evdev.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
commit 0e80804a2e8134e31d4d32679bdfff070fc64bca
Author: Dmitry Shmidt <dimitrysh@google.com>
Date: Tue Jan 31 11:06:23 2012 -0800
net: wireless: bcmdhd: Increase pm_notify callback priority
Make pm_notify callback to be called the first on suspend/resume path to
ensure it will always be called.
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
drivers/net/wireless/bcmdhd/dhd_linux.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
commit dfc896e1c833916ef5062294e2d675d66294ac68
Author: Dmitry Shmidt <dimitrysh@google.com>
Date: Mon Jan 30 15:43:31 2012 -0800
net: wireless: bcmdhd: Fix crash on dhdsdio_probe_attach() failure
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
drivers/net/wireless/bcmdhd/dhd_linux.c | 17 ++++++++++++++---
drivers/net/wireless/bcmdhd/dhd_sdio.c | 8 +++++++-
2 files changed, 21 insertions(+), 4 deletions(-)
commit 256a6b23be368f708672eb5929e961afc872f610
Author: Dmitry Shmidt <dimitrysh@google.com>
Date: Mon Jan 30 13:03:19 2012 -0800
net: wireless: bcmdhd: Daemonize wl_event_handler
Daemonizing makes thread (besides other things) NON-FREEZABLE, and it will not
get fake signal on suspend to quicl down_interruptible()
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
drivers/net/wireless/bcmdhd/dhd_linux.c | 13 -------------
drivers/net/wireless/bcmdhd/include/linuxver.h | 12 ++++++++++++
drivers/net/wireless/bcmdhd/wl_cfg80211.c | 3 +++
3 files changed, 15 insertions(+), 13 deletions(-)
commit ff93146589f6f28ba8a46f85e9b319bbd2cc8cfd
Author: Dmitry Shmidt <dimitrysh@google.com>
Date: Tue Jan 24 13:59:40 2012 -0800
net: wireless: bcmdhd: Update to Version 5.90.195.23
- WFD fixes
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
drivers/net/wireless/bcmdhd/dhd_cfg80211.c | 269 -------------------------
drivers/net/wireless/bcmdhd/dhd_linux.c | 2 +-
drivers/net/wireless/bcmdhd/dhd_sdio.c | 8 +-
drivers/net/wireless/bcmdhd/include/epivers.h | 8 +-
drivers/net/wireless/bcmdhd/siutils.c | 5 +
drivers/net/wireless/bcmdhd/wl_cfg80211.c | 223 +++++++++++++++------
drivers/net/wireless/bcmdhd/wl_cfgp2p.c | 175 ++++++++++++++++-
drivers/net/wireless/bcmdhd/wl_cfgp2p.h | 37 ++--
8 files changed, 368 insertions(+), 359 deletions(-)
commit 96034c20069fe841f4be741755f94671a328702e
Author: Dmitry Shmidt <dimitrysh@google.com>
Date: Tue Jan 24 13:55:00 2012 -0800
net: wireless: bcmdhd: Update to Version 5.90.195.22
- Disable Ad-hoc support for cfg80211
- dhd_linux.c: Fix incorrect pid check
- Merge Android changes from Android tree
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
drivers/net/wireless/bcmdhd/bcmsdh_linux.c | 24 ++------------------
drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c | 25 +++++++++++++++------
drivers/net/wireless/bcmdhd/dhd_linux.c | 10 ++++----
drivers/net/wireless/bcmdhd/dhd_sdio.c | 11 +++++++--
drivers/net/wireless/bcmdhd/hndpmu.c | 16 ++++++++++++++
drivers/net/wireless/bcmdhd/include/bcmdevs.h | 2 +
drivers/net/wireless/bcmdhd/include/epivers.h | 8 +++---
drivers/net/wireless/bcmdhd/siutils.c | 3 ++
drivers/net/wireless/bcmdhd/wl_cfg80211.c | 11 ++++++++-
9 files changed, 68 insertions(+), 42 deletions(-)
commit 494661a1acbd4767e4d7daaff8d7ce55328913d9
Author: Dmitry Shmidt <dimitrysh@google.com>
Date: Tue Jan 24 13:47:47 2012 -0800
net: wireless: bcmdhd: Update to Version 5.90.195.19
- Add WFD changes
- Add extra locking for internal ioctl operations
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
drivers/net/wireless/bcmdhd/Makefile | 4 +-
drivers/net/wireless/bcmdhd/bcmsdh_linux.c | 25 +-
drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c | 4 +-
drivers/net/wireless/bcmdhd/dhd.h | 10 +-
drivers/net/wireless/bcmdhd/dhd_cdc.c | 7 +-
drivers/net/wireless/bcmdhd/dhd_cfg80211.c | 862 ++++++++
drivers/net/wireless/bcmdhd/dhd_cfg80211.h | 42 +
drivers/net/wireless/bcmdhd/dhd_common.c | 7 +-
drivers/net/wireless/bcmdhd/dhd_linux.c | 103 +-
drivers/net/wireless/bcmdhd/dhd_linux_mon.c | 409 ----
drivers/net/wireless/bcmdhd/dhd_sdio.c | 4 +-
drivers/net/wireless/bcmdhd/include/dhdioctl.h | 3 +-
drivers/net/wireless/bcmdhd/include/epivers.h | 8 +-
drivers/net/wireless/bcmdhd/include/proto/802.11.h | 12 +-
drivers/net/wireless/bcmdhd/include/wlioctl.h | 19 +-
drivers/net/wireless/bcmdhd/wl_android.c | 22 +-
drivers/net/wireless/bcmdhd/wl_android.h | 2 +-
drivers/net/wireless/bcmdhd/wl_cfg80211.c | 2142 ++++++--------------
drivers/net/wireless/bcmdhd/wl_cfg80211.h | 125 +-
drivers/net/wireless/bcmdhd/wl_cfgp2p.c | 245 ++-
drivers/net/wireless/bcmdhd/wl_cfgp2p.h | 27 +-
drivers/net/wireless/bcmdhd/wl_linux_mon.c | 409 ++++
drivers/net/wireless/bcmdhd/wldev_common.c | 69 +-
drivers/net/wireless/bcmdhd/wldev_common.h | 20 +-
24 files changed, 2485 insertions(+), 2095 deletions(-)
commit 1dddb0cc0de2840a2fe43a02fcb0196bb5cb86c8
Author: Dmitry Shmidt <dimitrysh@google.com>
Date: Tue Jan 24 13:37:34 2012 -0800
net: wireless: bcmdhd: Update to Version 5.90.195.15
- Add WFD concurrent mode support
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
drivers/net/wireless/bcmdhd/bcmevent.c | 8 +-
drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c | 12 +-
drivers/net/wireless/bcmdhd/bcmutils.c | 4 +-
drivers/net/wireless/bcmdhd/dhd.h | 25 +-
drivers/net/wireless/bcmdhd/dhd_cdc.c | 9 +-
drivers/net/wireless/bcmdhd/dhd_common.c | 4 +-
drivers/net/wireless/bcmdhd/dhd_linux.c | 148 +++--
drivers/net/wireless/bcmdhd/dhd_linux_mon.c | 28 +-
drivers/net/wireless/bcmdhd/dhd_sdio.c | 27 +-
drivers/net/wireless/bcmdhd/dhd_wlfc.h | 12 +-
drivers/net/wireless/bcmdhd/hndpmu.c | 44 +-
drivers/net/wireless/bcmdhd/include/Makefile | 2 +-
drivers/net/wireless/bcmdhd/include/aidmp.h | 2 +-
drivers/net/wireless/bcmdhd/include/bcmcdc.h | 2 +-
drivers/net/wireless/bcmdhd/include/bcmdefs.h | 37 +-
drivers/net/wireless/bcmdhd/include/bcmdevs.h | 573 +++++++++++++-
drivers/net/wireless/bcmdhd/include/bcmendian.h | 2 +-
drivers/net/wireless/bcmdhd/include/bcmpcispi.h | 2 +-
drivers/net/wireless/bcmdhd/include/bcmperf.h | 2 +-
drivers/net/wireless/bcmdhd/include/bcmsdbus.h | 10 +-
drivers/net/wireless/bcmdhd/include/bcmsdh.h | 10 +-
drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h | 2 +-
drivers/net/wireless/bcmdhd/include/bcmsdpcm.h | 2 +-
drivers/net/wireless/bcmdhd/include/bcmsdspi.h | 2 +-
drivers/net/wireless/bcmdhd/include/bcmsdstd.h | 34 +-
drivers/net/wireless/bcmdhd/include/bcmspi.h | 2 +-
drivers/net/wireless/bcmdhd/include/bcmutils.h | 14 +-
drivers/net/wireless/bcmdhd/include/bcmwifi.h | 2 +-
drivers/net/wireless/bcmdhd/include/dhdioctl.h | 2 +-
drivers/net/wireless/bcmdhd/include/epivers.h | 14 +-
drivers/net/wireless/bcmdhd/include/hndpmu.h | 2 +-
.../net/wireless/bcmdhd/include/hndrte_armtrap.h | 2 +-
drivers/net/wireless/bcmdhd/include/hndrte_cons.h | 2 +-
drivers/net/wireless/bcmdhd/include/hndsoc.h | 2 +-
drivers/net/wireless/bcmdhd/include/htsf.h | 2 +-
drivers/net/wireless/bcmdhd/include/linux_osl.h | 2 +-
drivers/net/wireless/bcmdhd/include/linuxver.h | 6 +-
drivers/net/wireless/bcmdhd/include/miniopt.h | 2 +-
drivers/net/wireless/bcmdhd/include/msgtrace.h | 2 +-
drivers/net/wireless/bcmdhd/include/osl.h | 2 +-
.../wireless/bcmdhd/include/packed_section_end.h | 2 +-
.../wireless/bcmdhd/include/packed_section_start.h | 2 +-
drivers/net/wireless/bcmdhd/include/pcicfg.h | 28 +-
drivers/net/wireless/bcmdhd/include/proto/802.11.h | 317 +++++++-
.../net/wireless/bcmdhd/include/proto/802.11_bta.h | 2 +-
.../net/wireless/bcmdhd/include/proto/802.11e.h | 2 +-
drivers/net/wireless/bcmdhd/include/proto/802.1d.h | 2 +-
drivers/net/wireless/bcmdhd/include/proto/bcmeth.h | 2 +-
.../net/wireless/bcmdhd/include/proto/bcmevent.h | 9 +-
drivers/net/wireless/bcmdhd/include/proto/bcmip.h | 2 +-
.../net/wireless/bcmdhd/include/proto/bt_amp_hci.h | 2 +-
drivers/net/wireless/bcmdhd/include/proto/eapol.h | 2 +-
.../net/wireless/bcmdhd/include/proto/ethernet.h | 3 +-
drivers/net/wireless/bcmdhd/include/proto/p2p.h | 2 +-
drivers/net/wireless/bcmdhd/include/proto/sdspi.h | 2 +-
drivers/net/wireless/bcmdhd/include/proto/vlan.h | 2 +-
drivers/net/wireless/bcmdhd/include/proto/wpa.h | 12 +-
drivers/net/wireless/bcmdhd/include/sbchipc.h | 168 ++++-
drivers/net/wireless/bcmdhd/include/sbconfig.h | 2 +-
drivers/net/wireless/bcmdhd/include/sbhnddma.h | 6 +-
drivers/net/wireless/bcmdhd/include/sbpcmcia.h | 2 +-
drivers/net/wireless/bcmdhd/include/sbsdio.h | 2 +-
drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h | 2 +-
drivers/net/wireless/bcmdhd/include/sbsocram.h | 2 +-
drivers/net/wireless/bcmdhd/include/sdio.h | 5 +-
drivers/net/wireless/bcmdhd/include/sdioh.h | 32 +-
drivers/net/wireless/bcmdhd/include/sdiovar.h | 2 +-
drivers/net/wireless/bcmdhd/include/siutils.h | 30 +-
drivers/net/wireless/bcmdhd/include/trxhdr.h | 3 +-
drivers/net/wireless/bcmdhd/include/typedefs.h | 5 +-
drivers/net/wireless/bcmdhd/include/wlfc_proto.h | 2 +-
drivers/net/wireless/bcmdhd/include/wlioctl.h | 87 ++-
drivers/net/wireless/bcmdhd/linux_osl.c | 23 +-
drivers/net/wireless/bcmdhd/siutils.c | 195 +++++-
drivers/net/wireless/bcmdhd/wl_android.c | 6 +-
drivers/net/wireless/bcmdhd/wl_cfg80211.c | 875 ++++++++++++--------
drivers/net/wireless/bcmdhd/wl_cfg80211.h | 282 +++++---
drivers/net/wireless/bcmdhd/wl_cfgp2p.c | 165 ++++-
drivers/net/wireless/bcmdhd/wl_cfgp2p.h | 12 +-
drivers/net/wireless/bcmdhd/wl_iw.c | 110 +++-
drivers/net/wireless/bcmdhd/wl_iw.h | 17 +-
81 files changed, 2737 insertions(+), 752 deletions(-)
commit 52bdb6f54335bce7861d756ce1eb03ea9b7adb8f
Author: Dmitry Shmidt <dimitrysh@google.com>
Date: Mon Jan 23 12:47:21 2012 -0800
net: wireless: bcmdhd: Add WIPHY_FLAG_SUPPORTS_FW_ROAM flag
Adding this flag will allow NL80211_ATTR_ROAM_SUPPORT, and will set
WPA_DRIVER_FLAGS_BSS_SELECTION flag in wpa_supplicant
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
drivers/net/wireless/bcmdhd/wl_cfg80211.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
commit b1a94205e9ab943d4c18f8e0a081b32bc8bd1f50
Author: Dmitry Shmidt <dimitrysh@google.com>
Date: Fri Jan 20 14:15:05 2012 -0800
net: wireless: bcmdhd: Fake PNO event to wake up the wpa_supplicant
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
drivers/net/wireless/bcmdhd/dhd_linux.c | 4 +++-
drivers/net/wireless/bcmdhd/wl_cfg80211.c | 20 ++++++++++++++++----
2 files changed, 19 insertions(+), 5 deletions(-)
commit 09701e3edf03f92f4215aad83b32cd8cec7fb689
Author: Scott Anderson <saa@google.com>
Date: Wed Jan 18 15:56:51 2012 -0800
usb: gadget: android: Honor CONFIG_USB_GADGET_VBUS_DRAW
The maximum current draw was hard coded to 500 mA. composite.c
has code that uses CONFIG_USB_GADGET_VBUS_DRAW to set the
bMaxPower and to set whether or not the device is self-powered if
they haven't been set. This change removes the code in android.c
to allow composite.c to set them.
Change-Id: I9db37922e91ee86e9e5c0e14519e119e5c41ca48
Signed-off-by: Scott Anderson <saa@google.com>
drivers/usb/gadget/android.c | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)
commit a6ccb73389f3df11e788bf84254a7b27c430f949
Author: Benoit Goby <benoit@android.com>
Date: Fri Jan 20 14:42:41 2012 -0800
usb: gadget: Fix usb string id allocation
Don't reset next_string_id every time the gadget is enabled, this makes
the next strings allocated overwrite strings allocated at probe time.
Instead, fix rndis not to allocate new string ids on every config bind.
Change-Id: Ied28ee416bb6f00c434c34176fe5b7f0dcb2b2d4
Signed-off-by: Benoit Goby <benoit@android.com>
drivers/usb/gadget/android.c | 1 -
drivers/usb/gadget/f_rndis.c | 12 +++++-------
drivers/usb/gadget/rndis.c | 11 +++++++++++
3 files changed, 16 insertions(+), 8 deletions(-)
commit 87159de9c30dab02b84cbaffa7498140d4ebc1a1
Author: Jouni Malinen <jouni@qca.qualcomm.com>
Date: Thu Aug 11 11:46:22 2011 +0300
nl80211/cfg80211: Make addition of new sinfo fields safer
Add a comment pointing out the use of enum station_info_flags for
all new struct station_info fields. In addition, memset the sinfo
buffer to zero before use on all paths in the current tree to avoid
leaving uninitialized pointers in the data.
Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
include/net/cfg80211.h | 5 +++++
net/mac80211/sta_info.c | 1 +
net/wireless/nl80211.c | 1 +
3 files changed, 7 insertions(+), 0 deletions(-)
commit d692df224b8605095cb7f770c1c99d3150834daf
Author: Jouni Malinen <jouni@qca.qualcomm.com>
Date: Mon Aug 8 12:11:52 2011 +0300
cfg80211/nl80211: Send AssocReq IEs to user space in AP mode
When user space SME/MLME (e.g., hostapd) is not used in AP mode, the
IEs from the (Re)Association Request frame that was processed in
firmware need to be made available for user space (e.g., RSN IE for
hostapd). Allow this to be done with cfg80211_new_sta().
Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
Acked-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
include/net/cfg80211.h | 8 ++++++++
net/wireless/nl80211.c | 4 ++++
2 files changed, 12 insertions(+), 0 deletions(-)
commit d1e94136fc4fe8ea608f4e9d21befa00c86e1e29
Author: Dima Zavin <dima@android.com>
Date: Mon Jan 23 10:39:02 2012 -0800
misc: remove android pmem driver, it's obsolete.
Change-Id: I48d9778007e1e9eed2bb34e33ceee818c23afaa5
Signed-off-by: Dima Zavin <dima@android.com>
drivers/misc/Kconfig | 4 -
drivers/misc/Makefile | 1 -
drivers/misc/pmem.c | 1345 ------------------------------------------
include/linux/android_pmem.h | 93 ---
4 files changed, 0 insertions(+), 1443 deletions(-)
commit dac306d896642f3dfcd878ab6a0a5b8c123722f3
Author: Dima Zavin <dima@android.com>
Date: Thu Jan 19 09:51:07 2012 -0800
Revert "proc: enable writing to /proc/pid/mem"
This reverts commit 198214a7ee50375fa71a65e518341980cfd4b2f0.
fs/proc/base.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
commit a65e28a0149261776678977962cfa0f90973e1d4
Author: Dima Zavin <dima@android.com>
Date: Thu Jan 12 15:55:25 2012 -0800
ram_console: set CON_ANYTIME console flag
We want to ensure that we get all the console messages, even ones
that occur while the printing CPU is not yet online.
Change-Id: I1d2694d05ac9415669a92f38efdd8e71c927705b
Signed-off-by: Dima Zavin <dima@android.com>
drivers/staging/android/ram_console.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
commit f16e6fb3e3bbbc279579b3c3def7951787c88a0a
Author: Benoit Goby <benoit@android.com>
Date: Thu Dec 15 18:40:37 2011 -0800
Revert "usb: gadget: rndis: don't use dev_get_stats"
This reverts commit ffdab0c0c40bab6de78b1952bb07aed221994b73.
Not needed anymore in 2.6.39 and 3.0, dev_get_stats has been fixed
and may be called from atomic context. See:
1ac9ad1 net: remove dev_txq_stats_fold()
drivers/usb/gadget/rndis.c | 23 ++---------------------
1 files changed, 2 insertions(+), 21 deletions(-)
commit e1493f1544e804f228efd4a48a843bb1d81d2d2c
Author: Dmitry Shmidt <dimitrysh@google.com>
Date: Mon Dec 19 10:24:09 2011 -0800
net: wireless: bcmdhd: Enable wlan access on resume for all sdio functions
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
commit bbd08c6e95880dfc3bf1fe9b07486beb33a9cdd1
Author: Dmitry Shmidt <dimitrysh@google.com>
Date: Fri Dec 16 12:54:51 2011 -0800
net: wireless: bcmdhd: Fix P2P interface removal
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
drivers/net/wireless/bcmdhd/dhd_linux.c | 3 ++
drivers/net/wireless/bcmdhd/wl_cfg80211.c | 43 ++++++++++++++++++++++-------
drivers/net/wireless/bcmdhd/wl_cfg80211.h | 9 ++++--
3 files changed, 42 insertions(+), 13 deletions(-)
commit 37ff4411a5f5ce21feb3825296308f2a767e3662
Author: Dmitry Shmidt <dimitrysh@google.com>
Date: Thu Dec 15 12:12:20 2011 -0800
net: wireless: bcm4329: Fix pno_enable if disassociated
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
drivers/net/wireless/bcm4329/dhd_common.c | 43 ++++++++++++++++++++++++-----
1 files changed, 36 insertions(+), 7 deletions(-)
commit 599c8566fa1f34f297df6c683c23a213ff748d02
Author: Dmitry Shmidt <dimitrysh@google.com>
Date: Tue Dec 13 17:39:48 2011 -0800
net: wireless: bcmdhd: Fix proper scan command even if request is NULL
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
drivers/net/wireless/bcmdhd/wl_cfg80211.c | 16 ++++++++++------
1 files changed, 10 insertions(+), 6 deletions(-)
commit f227b88c89e84371e3897207ddab3877f6af6113
Author: Dmitry Shmidt <dimitrysh@google.com>
Date: Tue Dec 13 12:27:49 2011 -0800
net: wireless: bcmdhd: Decrease event wake_lock timeout to 1500 ms
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
drivers/net/wireless/bcmdhd/dhd.h | 4 ++--
drivers/net/wireless/bcmdhd/dhd_linux.c | 8 ++++----
drivers/net/wireless/bcmdhd/wl_iw.c | 2 +-
3 files changed, 7 insertions(+), 7 deletions(-)
commit ed3f35608786481035165a3b0321ab0b04768b5d
Author: Dmitry Shmidt <dimitrysh@google.com>
Date: Mon Dec 12 15:40:33 2011 -0800
net: wireless: bcmdhd: Fix getting arp_hostip table
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
drivers/net/wireless/bcmdhd/dhd_common.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
commit c561cedf2b6c9d6e7c26ee69dd17c97c0a852a17
Author: Dmitry Shmidt <dimitrysh@google.com>
Date: Tue Dec 6 16:27:37 2011 -0800
net: wireless: bcmdhd: Allow to push more packets to FW for Tx
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
drivers/net/wireless/bcmdhd/dhd_sdio.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
commit 4f36cb88d6e7e5afcdef42f6d2d70cbffbd2c541
Author: Dmitry Shmidt <dimitrysh@google.com>
Date: Fri Dec 2 13:24:01 2011 -0800
net: wireless: bcmdhd: Fix scan crash in ibss mode
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
drivers/net/wireless/bcmdhd/wl_cfg80211.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
commit af16732d4c98078988755337fb5e197fc31ca77e
Author: Dmitry Shmidt <dimitrysh@google.com>
Date: Fri Dec 2 13:10:47 2011 -0800
net: wireless: bcmdhd: Add FW reloading in case of FW hang
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
drivers/net/wireless/bcmdhd/dhd_linux.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
commit 7caeacd6ed135e2ee4fbbc26aa0fc0aea4cb166d
Author: Dmitry Shmidt <dimitrysh@google.com>
Date: Wed Nov 30 12:49:02 2011 -0800
net: wireless: bcmdhd: Update to Version 5.90.125.94.1
- Return zeroed private command buffer
- Fix memory leak in wl_inform_single_bss()
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
drivers/net/wireless/bcmdhd/dhd_common.c | 5 +++--
drivers/net/wireless/bcmdhd/dhd_linux_mon.c | 10 ++++++----
drivers/net/wireless/bcmdhd/include/epivers.h | 2 +-
drivers/net/wireless/bcmdhd/wl_android.c | 9 ++++++---
drivers/net/wireless/bcmdhd/wl_cfg80211.c | 9 ++++++---
5 files changed, 22 insertions(+), 13 deletions(-)
commit 8d71d882e7062dfbcdb2f790470f803cc536b8ae
Author: Dmitry Shmidt <dimitrysh@google.com>
Date: Fri Nov 11 16:04:12 2011 -0800
net: wireless: bcmdhd: Use CONFIG_DHD_USE_STATIC_BUF for preallocated memory
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
drivers/net/wireless/bcmdhd/Kconfig | 7 +++
drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c | 16 ++++----
drivers/net/wireless/bcmdhd/dhd.h | 4 +-
drivers/net/wireless/bcmdhd/dhd_cdc.c | 4 +-
drivers/net/wireless/bcmdhd/dhd_linux.c | 4 +-
drivers/net/wireless/bcmdhd/dhd_sdio.c | 4 +-
drivers/net/wireless/bcmdhd/include/linux_osl.h | 2 +-
drivers/net/wireless/bcmdhd/linux_osl.c | 52 +++++++++++++----------
drivers/net/wireless/bcmdhd/wl_android.c | 7 ++-
9 files changed, 57 insertions(+), 43 deletions(-)
commit 35047200c401cdd1bb43b5574270d1ac86a47937
Author: Dmitry Shmidt <dimitrysh@google.com>
Date: Mon Dec 19 12:32:21 2011 -0800
wireless: Protect regdomain change by mutex
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
net/wireless/reg.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
commit ea693bf7f87603b072f4ceea6684221fa0b8e863
Author: Dmitry Shmidt <dimitrysh@google.com>
Date: Fri Dec 16 17:52:18 2011 -0800
mmc: Set suspend/resume bus operations if CONFIG_PM_RUNTIME is used
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
drivers/mmc/core/bus.c | 24 +++++++-----------------
1 files changed, 7 insertions(+), 17 deletions(-)
commit dc1b6340394ef744e210247ab786df66639f5a33
Author: Benoit Goby <benoit@android.com>
Date: Fri Dec 9 18:05:00 2011 -0800
usb: gadget: android: Don't allow changing the functions list if enabled
Change-Id: I3ad39b420ce79a8602a7eca1daac1f56b30bad5c
Signed-off-by: Benoit Goby <benoit@android.com>
drivers/usb/gadget/android.c | 28 ++++++++++++++++++++++++----
1 files changed, 24 insertions(+), 4 deletions(-)
commit e0de0a507d83e84c833d01de9e46a44b12419431
Author: Benoit Goby <benoit@android.com>
Date: Tue Nov 29 13:49:27 2011 -0800
usb: gadget: android: Cancel pending ctrlrequest before disabling
Make sure there is no pending ctrlrequest before removing the config.
Otherwise the ctrlrequest complete callback could access structures
after they have been freed. Unbind cancels pending transfers but not
ep0 requests.
Bug: 5513065 5440193
Change-Id: I063c22bf5d104a3d2df71cf622409459fac5f27a
Signed-off-by: Benoit Goby <benoit@android.com>
drivers/usb/gadget/android.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
commit b86fd0b62252fbba6a5d6acda09fd325fb8e201b
Author: Colin Cross <ccross@android.com>
Date: Tue Nov 29 16:37:07 2011 -0800
ARM: idle: call idle notifiers before stopping nohz tick
If an idle notifier modifies a timer, calling the notifier after
the sched tick has been stopped may leave the sched tick set too
early. Move teh idle notifier call before the call to
tick_nohz_stop_sched_tick.
Change-Id: I0db3284bec6d0193bc5e2a57650ab06bd8342319
Signed-off-by: Colin Cross <ccross@android.com>
arch/arm/kernel/process.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
commit 6a4a38525d60db7e915d559273d8c89db5a98edf
Author: Benoit Goby <benoit@android.com>
Date: Mon Nov 28 18:01:03 2011 -0800
usb: gadget: android: Reset next_string_id before enable
Reset next_string_id to 0 before enabling the gadget driver. Otherwise,
after a large number of enable/disable cycles, bind will fail
because we cannot allocate new string ids. String ids cannot be larger
than 254 per USB spec.
Change-Id: I44f5fece45008b7a0a18c025d4eb5ce842585c28
Signed-off-by: Benoit Goby <benoit@android.com>
drivers/usb/gadget/android.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
commit dbb18fb2c1519b7810018580ee5123f9be73f213
Author: hyungseoung.yoo <hyungseoung.yoo@samsung.com>
Date: Fri Nov 18 13:57:01 2011 +0900
Bluetooth: Keep master role when SCO or eSCO is active
This improves compatbility with a lot of headset / chipset
combinations. Ideally this should not be needed.
Change-Id: I8b676701e12e416aa7d60801b9d353b15d102709
Signed-off-by: hyungseoung.yoo <hyungseoung.yoo@samsung.com>
Signed-off-by: Jaikumar Ganesh <jaikumarg@android.com>
net/bluetooth/hci_event.c | 12 +++++++++++-
1 files changed, 11 insertions(+), 1 deletions(-)
commit 9d187300dfeb825b3c851458427a7046d9302c06
Author: Arve Hjønnevåg <arve@android.com>
Date: Tue Nov 22 14:56:50 2011 -0800
rtc: Fix some bugs that allowed accumulating time drift in suspend/resume
The current code checks if abs(delta_delta.tv_sec) is greater or
equal to two before it discards the old delta value, but this can
trigger at close to -1 seconds since -1.000000001 seconds is stored
as tv_sec -2 and tv_nsec 999999999 in a normalized timespec.
rtc_resume had an early return check if the rtc value had not changed
since rtc_suspend. This effectivly stops time for the duration of the
short sleep. Check if sleep_time is positive after all the adjustments
have been applied instead since this allows the old_system adjustment
in rtc_suspend to have an effect even for short sleep cycles.
Change-Id: I00b45c0349ec91a4bab9b41a126b377515427898
Signed-off-by: Arve Hjønnevåg <arve@android.com>
drivers/rtc/class.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
commit 452d440ab295475afb04dee90879f5fb70254659
Author: Arve Hjønnevåg <arve@android.com>
Date: Tue Nov 22 15:28:27 2011 -0800
Fix "time: Catch invalid timespec sleep values in __timekeeping_inject_sleeptime" to compile on 3.0
Change-Id: I1225f279cda04dedbfb7f853f6b58f1032bd6d2b
kernel/time/timekeeping.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
commit cf70c6a40073530c9e23fb373a541c09996429c7
Author: John Stultz <john.stultz@linaro.org>
Date: Wed Jun 1 18:18:09 2011 -0700
time: Catch invalid timespec sleep values in __timekeeping_inject_sleeptime
Arve suggested making sure we catch possible negative sleep time
intervals that could be passed into timekeeping_inject_sleeptime.
CC: Arve Hjønnevåg <arve@android.com>
CC: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: John Stultz <john.stultz@linaro.org>
kernel/time/timekeeping.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
commit 340ede367101d47c8fd69e83e5e6db9077f4caad
Author: John Stultz <john.stultz@linaro.org>
Date: Fri May 27 11:33:18 2011 -0700
rtc: Avoid accumulating time drift in suspend/resume
Because the RTC interface is only a second granular interface,
each time we read from the RTC for suspend/resume, we introduce a
half second (on average) of error.
In order to avoid this error accumulating as the system is suspended
over and over, this patch measures the time delta between the RTC
and the system CLOCK_REALTIME.
If the delta is less then 2 seconds from the last suspend, we compensate
by using the previous time delta (keeping it close). If it is larger
then 2 seconds, we assume the clock was set or has been changed, so we
do no correction and update the delta.
Note: If NTP is running, ths could seem to "fight" with the NTP corrected
time, where as if the system time was off by 1 second, and NTP slewed the
value in, a suspend/resume cycle could undo this correction, by trying to
restore the previous offset from the RTC. However, without this patch,
since each read could cause almost a full second worth of error, its
possible to get almost 2 seconds of error just from the suspend/resume
cycle alone, so this about equal to any offset added by the compensation.
Further on systems that suspend/resume frequently, this should keep time
closer then NTP could compensate for if the errors were allowed to
accumulate.
Credits to Arve Hjønnevåg for suggesting this solution.
This patch also improves some of the variable names and adds more clear
comments.
CC: Arve Hjønnevåg <arve@android.com>
CC: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: John Stultz <john.stultz@linaro.org>
drivers/rtc/class.c | 65 +++++++++++++++++++++++++++++++++++++-------------
1 files changed, 48 insertions(+), 17 deletions(-)
Change-Id: I16f522e7ee2b301cbdaea62d52d50d7249f565c2
Signed-off-by: Rohit Vaswani <rvaswani@codeaurora.org>
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 4ee00c8..95015d8 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -226,8 +226,8 @@
/* endless idle loop with no priority at all */
while (1) {
- tick_nohz_stop_sched_tick(1);
idle_notifier_call_chain(IDLE_START);
+ tick_nohz_stop_sched_tick(1);
while (!need_resched()) {
#ifdef CONFIG_HOTPLUG_CPU
if (cpu_is_offline(smp_processor_id()))
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 6e7dd68..6288d7d 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -45,6 +45,7 @@
unsigned int packet_head; /* [future] position of the first element of next packet */
spinlock_t buffer_lock; /* protects access to buffer, head and tail */
struct wake_lock wake_lock;
+ bool use_wake_lock;
char name[28];
struct fasync_struct *fasync;
struct evdev *evdev;
@@ -62,7 +63,6 @@
/* Interrupts are disabled, just acquire the lock. */
spin_lock(&client->buffer_lock);
- wake_lock_timeout(&client->wake_lock, 5 * HZ);
client->buffer[client->head++] = *event;
client->head &= client->bufsize - 1;
@@ -79,10 +79,14 @@
client->buffer[client->tail].value = 0;
client->packet_head = client->tail;
+ if (client->use_wake_lock)
+ wake_unlock(&client->wake_lock);
}
if (event->type == EV_SYN && event->code == SYN_REPORT) {
client->packet_head = client->head;
+ if (client->use_wake_lock)
+ wake_lock(&client->wake_lock);
kill_fasync(&client->fasync, SIGIO, POLL_IN);
}
@@ -262,7 +266,8 @@
mutex_unlock(&evdev->mutex);
evdev_detach_client(evdev, client);
- wake_lock_destroy(&client->wake_lock);
+ if (client->use_wake_lock)
+ wake_lock_destroy(&client->wake_lock);
kfree(client);
evdev_close_device(evdev);
@@ -316,7 +321,6 @@
spin_lock_init(&client->buffer_lock);
snprintf(client->name, sizeof(client->name), "%s-%d",
dev_name(&evdev->dev), task_tgid_vnr(current));
- wake_lock_init(&client->wake_lock, WAKE_LOCK_SUSPEND, client->name);
client->evdev = evdev;
evdev_attach_client(evdev, client);
@@ -331,7 +335,6 @@
err_free_client:
evdev_detach_client(evdev, client);
- wake_lock_destroy(&client->wake_lock);
kfree(client);
err_put_evdev:
put_device(&evdev->dev);
@@ -385,7 +388,8 @@
if (have_event) {
*event = client->buffer[client->tail++];
client->tail &= client->bufsize - 1;
- if (client->head == client->tail)
+ if (client->use_wake_lock &&
+ client->packet_head == client->tail)
wake_unlock(&client->wake_lock);
}
@@ -635,6 +639,35 @@
return input_set_keycode(dev, &ke);
}
+static int evdev_enable_suspend_block(struct evdev *evdev,
+ struct evdev_client *client)
+{
+ if (client->use_wake_lock)
+ return 0;
+
+ spin_lock_irq(&client->buffer_lock);
+ wake_lock_init(&client->wake_lock, WAKE_LOCK_SUSPEND, client->name);
+ client->use_wake_lock = true;
+ if (client->packet_head != client->tail)
+ wake_lock(&client->wake_lock);
+ spin_unlock_irq(&client->buffer_lock);
+ return 0;
+}
+
+static int evdev_disable_suspend_block(struct evdev *evdev,
+ struct evdev_client *client)
+{
+ if (!client->use_wake_lock)
+ return 0;
+
+ spin_lock_irq(&client->buffer_lock);
+ client->use_wake_lock = false;
+ wake_lock_destroy(&client->wake_lock);
+ spin_unlock_irq(&client->buffer_lock);
+
+ return 0;
+}
+
static long evdev_do_ioctl(struct file *file, unsigned int cmd,
void __user *p, int compat_mode)
{
@@ -708,6 +741,15 @@
case EVIOCSKEYCODE_V2:
return evdev_handle_set_keycode_v2(dev, p);
+
+ case EVIOCGSUSPENDBLOCK:
+ return put_user(client->use_wake_lock, ip);
+
+ case EVIOCSSUSPENDBLOCK:
+ if (p)
+ return evdev_enable_suspend_block(evdev, client);
+ else
+ return evdev_disable_suspend_block(evdev, client);
}
size = _IOC_SIZE(cmd);
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index e854149..84983e0 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -120,7 +120,8 @@
return 0;
}
-static int mmc_bus_suspend(struct device *dev)
+#ifdef CONFIG_PM_SLEEP
+static int mmc_bus_pm_suspend(struct device *dev)
{
struct mmc_driver *drv = to_mmc_driver(dev->driver);
struct mmc_card *card = mmc_dev_to_card(dev);
@@ -131,7 +132,7 @@
return ret;
}
-static int mmc_bus_resume(struct device *dev)
+static int mmc_bus_pm_resume(struct device *dev)
{
struct mmc_driver *drv = to_mmc_driver(dev->driver);
struct mmc_card *card = mmc_dev_to_card(dev);
@@ -141,9 +142,9 @@
ret = drv->resume(card);
return ret;
}
+#endif
#ifdef CONFIG_PM_RUNTIME
-
static int mmc_runtime_suspend(struct device *dev)
{
struct mmc_card *card = mmc_dev_to_card(dev);
@@ -162,19 +163,11 @@
{
return pm_runtime_suspend(dev);
}
-
-#else /* !CONFIG_PM_RUNTIME */
-#define mmc_runtime_suspend NULL
-#define mmc_runtime_resume NULL
-#define mmc_runtime_idle NULL
-#endif /* !CONFIG_PM_RUNTIME */
+#endif /* CONFIG_PM_RUNTIME */
static const struct dev_pm_ops mmc_bus_pm_ops = {
- .runtime_suspend = mmc_runtime_suspend,
- .runtime_resume = mmc_runtime_resume,
- .runtime_idle = mmc_runtime_idle,
- .suspend = mmc_bus_suspend,
- .resume = mmc_bus_resume,
+ SET_SYSTEM_SLEEP_PM_OPS(mmc_bus_pm_suspend, mmc_bus_pm_resume)
+ SET_RUNTIME_PM_OPS(mmc_runtime_suspend, mmc_runtime_resume, mmc_runtime_idle)
};
static struct bus_type mmc_bus_type = {
diff --git a/drivers/net/wireless/bcm4329/dhd_common.c b/drivers/net/wireless/bcm4329/dhd_common.c
index f7cd372..8b89e39 100644
--- a/drivers/net/wireless/bcm4329/dhd_common.c
+++ b/drivers/net/wireless/bcm4329/dhd_common.c
@@ -1896,6 +1896,41 @@
#endif
+/*
+ * returns = TRUE if associated, FALSE if not associated
+ */
+bool is_associated(dhd_pub_t *dhd, void *bss_buf)
+{
+ char bssid[ETHER_ADDR_LEN], zbuf[ETHER_ADDR_LEN];
+ int ret = -1;
+
+ bzero(bssid, ETHER_ADDR_LEN);
+ bzero(zbuf, ETHER_ADDR_LEN);
+
+ ret = dhdcdc_set_ioctl(dhd, 0, WLC_GET_BSSID, (char *)bssid, ETHER_ADDR_LEN);
+ DHD_TRACE((" %s WLC_GET_BSSID ioctl res = %d\n", __FUNCTION__, ret));
+
+ if (ret == BCME_NOTASSOCIATED) {
+ DHD_TRACE(("%s: not associated! res:%d\n", __FUNCTION__, ret));
+ }
+
+ if (ret < 0)
+ return FALSE;
+
+ if ((memcmp(bssid, zbuf, ETHER_ADDR_LEN) != 0)) {
+ /* STA is assocoated BSSID is non zero */
+
+ if (bss_buf) {
+ /* return bss if caller provided buf */
+ memcpy(bss_buf, bssid, ETHER_ADDR_LEN);
+ }
+ return TRUE;
+ } else {
+ DHD_TRACE(("%s: WLC_GET_BSSID ioctl returned zero bssid\n", __FUNCTION__));
+ return FALSE;
+ }
+}
+
/* Function to estimate possible DTIM_SKIP value */
int dhd_get_dtim_skip(dhd_pub_t *dhd)
{
@@ -1979,7 +2014,6 @@
int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled)
{
char iovbuf[128];
- uint8 bssid[6];
int ret = -1;
if ((!dhd) && ((pfn_enabled != 0) || (pfn_enabled != 1))) {
@@ -1990,12 +2024,7 @@
memset(iovbuf, 0, sizeof(iovbuf));
/* Check if disassoc to enable pno */
- if ((pfn_enabled) && \
- ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_GET_BSSID, \
- (char *)&bssid, ETHER_ADDR_LEN)) == BCME_NOTASSOCIATED)) {
- DHD_TRACE(("%s pno enable called in disassoc mode\n", __FUNCTION__));
- }
- else if (pfn_enabled) {
+ if (pfn_enabled && (is_associated(dhd, NULL) == TRUE)) {
DHD_ERROR(("%s pno enable called in assoc mode ret=%d\n", \
__FUNCTION__, ret));
return ret;
diff --git a/drivers/net/wireless/bcmdhd/Kconfig b/drivers/net/wireless/bcmdhd/Kconfig
index db434ab..205c813 100644
--- a/drivers/net/wireless/bcmdhd/Kconfig
+++ b/drivers/net/wireless/bcmdhd/Kconfig
@@ -31,3 +31,10 @@
select WEXT_PRIV
help
Enables WEXT support
+
+config DHD_USE_STATIC_BUF
+ bool "Enable memory preallocation"
+ depends on BCMDHD
+ default n
+ ---help---
+ Use memory preallocated in platform
\ No newline at end of file
diff --git a/drivers/net/wireless/bcmdhd/Makefile b/drivers/net/wireless/bcmdhd/Makefile
index e82c985..17f07ca 100644
--- a/drivers/net/wireless/bcmdhd/Makefile
+++ b/drivers/net/wireless/bcmdhd/Makefile
@@ -13,7 +13,7 @@
DHDOFILES = aiutils.o bcmsdh_sdmmc_linux.o dhd_linux.o siutils.o bcmutils.o \
dhd_linux_sched.o bcmwifi.o dhd_sdio.o bcmevent.o dhd_bta.o hndpmu.o \
bcmsdh.o dhd_cdc.o bcmsdh_linux.o dhd_common.o linux_osl.o \
- bcmsdh_sdmmc.o dhd_custom_gpio.o sbutils.o wldev_common.o wl_android.o
+ bcmsdh_sdmmc.o dhd_custom_gpio.o sbutils.o wldev_common.o wl_android.o dhd_cfg80211.o
obj-$(CONFIG_BCMDHD) += bcmdhd.o
bcmdhd-objs += $(DHDOFILES)
@@ -22,7 +22,7 @@
DHDCFLAGS += -DSOFTAP
endif
ifneq ($(CONFIG_CFG80211),)
-bcmdhd-objs += wl_cfg80211.o wl_cfgp2p.o dhd_linux_mon.o
+bcmdhd-objs += wl_cfg80211.o wl_cfgp2p.o wl_linux_mon.o
DHDCFLAGS += -DWL_CFG80211
endif
EXTRA_CFLAGS = $(DHDCFLAGS)
diff --git a/drivers/net/wireless/bcmdhd/bcmevent.c b/drivers/net/wireless/bcmdhd/bcmevent.c
index 24581dd..6a25d9a 100644
--- a/drivers/net/wireless/bcmdhd/bcmevent.c
+++ b/drivers/net/wireless/bcmdhd/bcmevent.c
@@ -20,7 +20,7 @@
* Notwithstanding the above, under no circumstances may you combine this
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
- * $Id: bcmevent.c,v 1.8.2.7 2011-02-01 06:23:39 Exp $
+ * $Id: bcmevent.c,v 1.8.2.7 2011-02-01 06:23:39 $
*/
#include <typedefs.h>
@@ -29,7 +29,7 @@
#include <proto/bcmeth.h>
#include <proto/bcmevent.h>
-#if WLC_E_LAST != 85
+#if WLC_E_LAST != 87
#error "You need to add an entry to bcmevent_names[] for the new event"
#endif
@@ -117,8 +117,10 @@
{ WLC_E_PFN_SCAN_NONE, "PFN_SCAN_NONE" },
{ WLC_E_PFN_SCAN_ALLGONE, "PFN_SCAN_ALLGONE" },
#ifdef SOFTAP
- { WLC_E_GTK_PLUMBED, "GTK_PLUMBED" }
+ { WLC_E_GTK_PLUMBED, "GTK_PLUMBED" },
#endif
+ { WLC_E_ASSOC_REQ_IE, "ASSOC_REQ_IE" },
+ { WLC_E_ASSOC_RESP_IE, "ASSOC_RESP_IE" }
};
diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_linux.c b/drivers/net/wireless/bcmdhd/bcmsdh_linux.c
index 04c43a3..e01b6f8 100644
--- a/drivers/net/wireless/bcmdhd/bcmsdh_linux.c
+++ b/drivers/net/wireless/bcmdhd/bcmsdh_linux.c
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: bcmsdh_linux.c,v 1.72.6.5 2010-12-23 01:13:15 Exp $
+ * $Id: bcmsdh_linux.c 308641 2012-01-17 02:18:02Z $
*/
/**
@@ -147,17 +147,6 @@
#endif /* BCMLXSDMMC */
#ifndef BCMLXSDMMC
-static struct device_driver bcmsdh_driver = {
- .name = "pxa2xx-mci",
- .bus = &platform_bus_type,
- .probe = bcmsdh_probe,
- .remove = bcmsdh_remove,
- .suspend = NULL,
- .resume = NULL,
- };
-#endif /* BCMLXSDMMC */
-
-#ifndef BCMLXSDMMC
static
#endif /* BCMLXSDMMC */
int bcmsdh_probe(struct device *dev)
@@ -238,9 +227,9 @@
/* chain SDIO Host Controller info together */
sdhc->next = sdhcinfo;
sdhcinfo = sdhc;
+
/* Read the vendor/device ID from the CIS */
vendevid = bcmsdh_query_device(sdh);
-
/* try to attach to the target device */
if (!(sdhc->ch = drvinfo.attach((vendevid >> 16),
(vendevid & 0xFFFF), 0, 0, 0, 0,
@@ -274,6 +263,7 @@
sdhc = sdhcinfo;
drvinfo.detach(sdhc->ch);
bcmsdh_detach(sdhc->osh, sdhc->sdh);
+
/* find the SDIO Host Controller state for this pdev and take it out from the list */
for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) {
if (sdhc->dev == (void *)dev) {
@@ -290,7 +280,6 @@
return 0;
}
-
/* release SDIO Host Controller info */
osh = sdhc->osh;
MFREE(osh, sdhc, sizeof(bcmsdh_hc_t));
@@ -531,13 +520,8 @@
drvinfo = *driver;
#if defined(BCMPLATFORM_BUS)
-#if defined(BCMLXSDMMC)
SDLX_MSG(("Linux Kernel SDIO/MMC Driver\n"));
error = sdio_function_init();
-#else
- SDLX_MSG(("Intel PXA270 SDIO Driver\n"));
- error = driver_register(&bcmsdh_driver);
-#endif /* defined(BCMLXSDMMC) */
return error;
#endif /* defined(BCMPLATFORM_BUS) */
@@ -565,14 +549,12 @@
if (bcmsdh_pci_driver.node.next)
#endif
-#if defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC)
- driver_unregister(&bcmsdh_driver);
-#endif
#if defined(BCMLXSDMMC)
sdio_function_cleanup();
#endif /* BCMLXSDMMC */
+
#if !defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC)
- pci_unregister_driver(&bcmsdh_pci_driver);
+ pci_unregister_driver(&bcmsdh_pci_driver);
#endif /* BCMPLATFORM_BUS */
}
@@ -611,13 +593,6 @@
return IRQ_HANDLED;
}
-void *bcmsdh_get_drvdata(void)
-{
- if (!sdhcinfo)
- return NULL;
- return dev_get_drvdata(sdhcinfo->dev);
-}
-
int bcmsdh_register_oob_intr(void * dhdp)
{
int error = 0;
@@ -645,6 +620,13 @@
return 0;
}
+void *bcmsdh_get_drvdata(void)
+{
+ if (!sdhcinfo)
+ return NULL;
+ return dev_get_drvdata(sdhcinfo->dev);
+}
+
void bcmsdh_set_irq(int flag)
{
if (sdhcinfo->oob_irq_registered && sdhcinfo->oob_irq_enable_flag != flag) {
@@ -671,6 +653,7 @@
}
}
#endif /* defined(OOB_INTR_ONLY) */
+
/* Module parameters specific to each host-controller driver */
extern uint sd_msglevel; /* Debug message level */
@@ -694,6 +677,10 @@
extern uint sd_f2_blocksize;
module_param(sd_f2_blocksize, int, 0);
+#ifdef BCMSDIOH_STD
+extern int sd_uhsimode;
+module_param(sd_uhsimode, int, 0);
+#endif
#ifdef BCMSDH_MODULE
EXPORT_SYMBOL(bcmsdh_attach);
diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c
index 70bacbd3..6a8ff94 100644
--- a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c
+++ b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: bcmsdh_sdmmc.c 282820 2011-09-09 15:40:35Z $
+ * $Id: bcmsdh_sdmmc.c 301794 2011-12-08 20:41:35Z $
*/
#include <typedefs.h>
@@ -448,6 +448,7 @@
bcopy(params, &int_val, sizeof(int_val));
bool_val = (int_val != 0) ? TRUE : FALSE;
+ BCM_REFERENCE(bool_val);
actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid);
switch (actionid) {
@@ -1002,11 +1003,11 @@
if (pkt == NULL) {
sd_data(("%s: Creating new %s Packet, len=%d\n",
__FUNCTION__, write ? "TX" : "RX", buflen_u));
-#ifdef DHD_USE_STATIC_BUF
+#ifdef CONFIG_DHD_USE_STATIC_BUF
if (!(mypkt = PKTGET_STATIC(sd->osh, buflen_u, write ? TRUE : FALSE))) {
#else
if (!(mypkt = PKTGET(sd->osh, buflen_u, write ? TRUE : FALSE))) {
-#endif /* DHD_USE_STATIC_BUF */
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
sd_err(("%s: PKTGET failed: len %d\n",
__FUNCTION__, buflen_u));
return SDIOH_API_RC_FAIL;
@@ -1023,11 +1024,11 @@
if (!write) {
bcopy(PKTDATA(sd->osh, mypkt), buffer, buflen_u);
}
-#ifdef DHD_USE_STATIC_BUF
+#ifdef CONFIG_DHD_USE_STATIC_BUF
PKTFREE_STATIC(sd->osh, mypkt, write ? TRUE : FALSE);
#else
PKTFREE(sd->osh, mypkt, write ? TRUE : FALSE);
-#endif /* DHD_USE_STATIC_BUF */
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
} else if (((uint32)(PKTDATA(sd->osh, pkt)) & DMA_ALIGN_MASK) != 0) {
/* Case 2: We have a packet, but it is unaligned. */
@@ -1036,11 +1037,11 @@
sd_data(("%s: Creating aligned %s Packet, len=%d\n",
__FUNCTION__, write ? "TX" : "RX", PKTLEN(sd->osh, pkt)));
-#ifdef DHD_USE_STATIC_BUF
+#ifdef CONFIG_DHD_USE_STATIC_BUF
if (!(mypkt = PKTGET_STATIC(sd->osh, PKTLEN(sd->osh, pkt), write ? TRUE : FALSE))) {
#else
if (!(mypkt = PKTGET(sd->osh, PKTLEN(sd->osh, pkt), write ? TRUE : FALSE))) {
-#endif /* DHD_USE_STATIC_BUF */
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
sd_err(("%s: PKTGET failed: len %d\n",
__FUNCTION__, PKTLEN(sd->osh, pkt)));
return SDIOH_API_RC_FAIL;
@@ -1061,11 +1062,11 @@
PKTDATA(sd->osh, pkt),
PKTLEN(sd->osh, mypkt));
}
-#ifdef DHD_USE_STATIC_BUF
+#ifdef CONFIG_DHD_USE_STATIC_BUF
PKTFREE_STATIC(sd->osh, mypkt, write ? TRUE : FALSE);
#else
PKTFREE(sd->osh, mypkt, write ? TRUE : FALSE);
-#endif /* DHD_USE_STATIC_BUF */
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
} else { /* case 3: We have a packet and it is aligned. */
sd_data(("%s: Aligned %s Packet, direct DMA\n",
__FUNCTION__, write ? "Tx" : "Rx"));
@@ -1179,6 +1180,7 @@
sd = gInstance->sd;
ASSERT(sd != NULL);
+ BCM_REFERENCE(sd);
}
#endif /* !defined(OOB_INTR_ONLY) */
diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
index 726b639..83f4d3d 100644
--- a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
+++ b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: bcmsdh_sdmmc_linux.c,v 1.8.6.2 2011-02-01 18:38:36 Exp $
+ * $Id: bcmsdh_sdmmc_linux.c 308645 2012-01-17 02:33:26Z $
*/
#include <typedefs.h>
@@ -55,13 +55,22 @@
#if !defined(SDIO_DEVICE_ID_BROADCOM_4319)
#define SDIO_DEVICE_ID_BROADCOM_4319 0x4319
#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4319) */
+#if !defined(SDIO_DEVICE_ID_BROADCOM_4330)
+#define SDIO_DEVICE_ID_BROADCOM_4330 0x4330
+#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4330) */
+#if !defined(SDIO_DEVICE_ID_BROADCOM_4334)
+#define SDIO_DEVICE_ID_BROADCOM_4334 0x4334
+#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4334) */
+#if !defined(SDIO_DEVICE_ID_BROADCOM_43239)
+#define SDIO_DEVICE_ID_BROADCOM_43239 43239
+#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_43239) */
#include <bcmsdh_sdmmc.h>
#include <dhd_dbg.h>
#ifdef WL_CFG80211
-extern void wl_cfg80211_set_sdio_func(void *func);
+extern void wl_cfg80211_set_parent_dev(void *dev);
#endif
extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd);
@@ -118,7 +127,7 @@
if (func->num == 2) {
#ifdef WL_CFG80211
- wl_cfg80211_set_sdio_func(func);
+ wl_cfg80211_set_parent_dev(&func->dev);
#endif
sd_trace(("F2 found, calling bcmsdh_probe...\n"));
ret = bcmsdh_probe(&func->dev);
@@ -153,6 +162,9 @@
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325) },
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329) },
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4319) },
+ { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330) },
+ { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334) },
+ { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43239) },
{ SDIO_DEVICE_CLASS(SDIO_CLASS_NONE) },
{ /* end: all zeroes */ },
};
@@ -166,11 +178,14 @@
if (func->num != 2)
return 0;
+
+ sd_trace(("%s Enter\n", __FUNCTION__));
+
if (dhd_os_check_wakelock(bcmsdh_get_drvdata()))
return -EBUSY;
#if defined(OOB_INTR_ONLY)
bcmsdh_oob_intr_set(0);
-#endif
+#endif /* defined(OOB_INTR_ONLY) */
dhd_mmc_suspend = TRUE;
smp_mb();
@@ -181,13 +196,13 @@
{
struct sdio_func *func = dev_to_sdio_func(pdev);
- if (func->num != 2)
- return 0;
+ sd_trace(("%s Enter\n", __FUNCTION__));
dhd_mmc_suspend = FALSE;
#if defined(OOB_INTR_ONLY)
- if (dhd_os_check_if_up(bcmsdh_get_drvdata()))
+ if ((func->num == 2) && dhd_os_check_if_up(bcmsdh_get_drvdata()))
bcmsdh_oob_intr_set(1);
-#endif
+#endif /* (OOB_INTR_ONLY) */
+
smp_mb();
return 0;
}
@@ -196,7 +211,7 @@
.suspend = bcmsdh_sdmmc_suspend,
.resume = bcmsdh_sdmmc_resume,
};
-#endif
+#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM) */
static struct sdio_driver bcmsdh_sdmmc_driver = {
.probe = bcmsdh_sdmmc_probe,
@@ -207,7 +222,7 @@
.drv = {
.pm = &bcmsdh_sdmmc_pm_ops,
},
-#endif
+#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM) */
};
struct sdos_info {
diff --git a/drivers/net/wireless/bcmdhd/bcmutils.c b/drivers/net/wireless/bcmdhd/bcmutils.c
index fbdd7cd..6b578e6 100644
--- a/drivers/net/wireless/bcmdhd/bcmutils.c
+++ b/drivers/net/wireless/bcmdhd/bcmutils.c
@@ -20,7 +20,7 @@
* Notwithstanding the above, under no circumstances may you combine this
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
- * $Id: bcmutils.c,v 1.277.2.18 2011-01-26 02:32:08 Exp $
+ * $Id: bcmutils.c,v 1.277.2.18 2011-01-26 02:32:08 $
*/
#include <typedefs.h>
@@ -987,7 +987,6 @@
return (rc | priority);
}
-#ifndef BCM_BOOTLOADER
static char bcm_undeferrstr[32];
static const char *bcmerrorstrtable[] = BCMERRSTRINGTABLE;
@@ -1009,7 +1008,6 @@
return bcmerrorstrtable[-bcmerror];
}
-#endif /* !BCM_BOOTLOADER */
diff --git a/drivers/net/wireless/bcmdhd/dhd.h b/drivers/net/wireless/bcmdhd/dhd.h
index c87f6cf..25e74f4 100644
--- a/drivers/net/wireless/bcmdhd/dhd.h
+++ b/drivers/net/wireless/bcmdhd/dhd.h
@@ -24,7 +24,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: dhd.h 290844 2011-10-20 08:54:39Z $
+ * $Id: dhd.h 306879 2012-01-09 21:33:03Z $
*/
/****************
@@ -83,6 +83,9 @@
/* max sequential rxcntl timeouts to set HANG event */
#define MAX_CNTL_TIMEOUT 2
+#define DHD_SCAN_ACTIVE_TIME 40 /* ms : Embedded default Active setting from DHD Driver */
+#define DHD_SCAN_PASSIVE_TIME 130 /* ms: Embedded default Passive setting from DHD Driver */
+
enum dhd_bus_wake_state {
WAKE_LOCK_OFF,
WAKE_LOCK_PRIV,
@@ -116,7 +119,7 @@
} dhd_if_state_t;
-#if defined(DHD_USE_STATIC_BUF)
+#if defined(CONFIG_DHD_USE_STATIC_BUF)
uint8* dhd_os_prealloc(void *osh, int section, uint size);
void dhd_os_prefree(void *osh, void *addr, uint size);
@@ -128,7 +131,7 @@
#define DHD_OS_PREALLOC(osh, section, size) MALLOC(osh, size)
#define DHD_OS_PREFREE(osh, addr, size) MFREE(osh, addr, size)
-#endif /* defined(DHD_USE_STATIC_BUF) */
+#endif /* defined(CONFIG_DHD_USE_STATIC_BUF) */
/* Packet alignment for most efficient SDIO (can change based on platform) */
#ifndef DHD_SDALIGN
@@ -314,8 +317,8 @@
#define DHD_OS_WAKE_LOCK_TIMEOUT(pub) dhd_os_wake_lock_timeout(pub)
#define DHD_OS_WAKE_LOCK_TIMEOUT_ENABLE(pub, val) dhd_os_wake_lock_timeout_enable(pub, val)
-#define DHD_PACKET_TIMEOUT 1
-#define DHD_EVENT_TIMEOUT 2
+#define DHD_PACKET_TIMEOUT_MS 1000
+#define DHD_EVENT_TIMEOUT_MS 1500
/* interface operations (register, remove) should be atomic, use this lock to prevent race
* condition among wifi on/off and interface operation functions
@@ -365,6 +368,11 @@
* bus_hdrlen specifies required headroom for bus module header.
*/
extern dhd_pub_t *dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen);
+#if defined(WLP2P) && defined(WL_CFG80211)
+/* To allow attach/detach calls corresponding to p2p0 interface */
+extern int dhd_attach_p2p(dhd_pub_t *);
+extern int dhd_detach_p2p(dhd_pub_t *);
+#endif /* WLP2P && WL_CFG80211 */
extern int dhd_net_attach(dhd_pub_t *dhdp, int idx);
/* Indication from bus module regarding removal/absence of dongle */
@@ -411,6 +419,9 @@
extern void dhd_os_sdunlock_sndup_rxq(dhd_pub_t * pub);
extern void dhd_os_sdlock_eventq(dhd_pub_t * pub);
extern void dhd_os_sdunlock_eventq(dhd_pub_t * pub);
+extern bool dhd_os_check_hang(dhd_pub_t *dhdp, int ifidx, int ret);
+
+#ifdef PNO_SUPPORT
extern int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled);
extern int dhd_pno_clean(dhd_pub_t *dhd);
extern int dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid,
@@ -421,9 +432,7 @@
int nssid, ushort scan_fr, int pno_repeat, int pno_freq_expo_max);
extern int dhd_dev_pno_enable(struct net_device *dev, int pfn_enabled);
extern int dhd_dev_get_pno_status(struct net_device *dev);
-extern int dhd_get_dtim_skip(dhd_pub_t *dhd);
-extern bool dhd_check_ap_wfd_mode_set(dhd_pub_t *dhd);
-extern bool dhd_os_check_hang(dhd_pub_t *dhdp, int ifidx, int ret);
+#endif /* PNO_SUPPORT */
#define DHD_UNICAST_FILTER_NUM 0
#define DHD_BROADCAST_FILTER_NUM 1
@@ -432,6 +441,9 @@
extern int net_os_set_packet_filter(struct net_device *dev, int val);
extern int net_os_rxfilter_add_remove(struct net_device *dev, int val, int num);
+extern int dhd_get_dtim_skip(dhd_pub_t *dhd);
+extern bool dhd_check_ap_wfd_mode_set(dhd_pub_t *dhd);
+
#ifdef DHD_DEBUG
extern int write_to_file(dhd_pub_t *dhd, uint8 *buf, int size);
#endif /* DHD_DEBUG */
@@ -453,7 +465,7 @@
extern int dhd_ifname2idx(struct dhd_info *dhd, char *name);
extern int dhd_net2idx(struct dhd_info *dhd, struct net_device *net);
-extern struct net_device * dhd_idx2net(struct dhd_pub *dhd_pub, int ifidx);
+extern struct net_device * dhd_idx2net(void *pub, int ifidx);
extern int wl_host_event(dhd_pub_t *dhd_pub, int *idx, void *pktdata,
wl_event_msg_t *, void **data_ptr);
extern void wl_event_to_host_order(wl_event_msg_t * evt);
@@ -465,6 +477,7 @@
extern struct dhd_cmn *dhd_common_init(osl_t *osh);
extern void dhd_common_deinit(dhd_pub_t *dhd_pub, dhd_cmn_t *sa_cmn);
+extern int dhd_do_driver_init(struct net_device *net);
extern int dhd_add_if(struct dhd_info *dhd, int ifidx, void *handle,
char *name, uint8 *mac_addr, uint32 flags, uint8 bssidx);
extern void dhd_del_if(struct dhd_info *dhd, int ifidx);
@@ -701,12 +714,6 @@
#define DHD_PKTTAG_DSTN(tag) ((dhd_pkttag_t*)(tag))->dstn_ether
typedef int (*f_commitpkt_t)(void* ctx, void* p);
-int dhd_wlfc_enable(dhd_pub_t *dhd);
-int dhd_wlfc_interface_event(struct dhd_info *, uint8 action, uint8 ifid, uint8 iftype, uint8* ea);
-int dhd_wlfc_FIFOcreditmap_event(struct dhd_info *dhd, uint8* event_data);
-int dhd_wlfc_event(struct dhd_info *dhd);
-int dhd_os_wlfc_block(dhd_pub_t *pub);
-int dhd_os_wlfc_unblock(dhd_pub_t *pub);
#ifdef PROP_TXSTATUS_DEBUG
#define DHD_WLFC_CTRINC_MAC_CLOSE(entry) do { (entry)->closed_ct++; } while (0)
diff --git a/drivers/net/wireless/bcmdhd/dhd_cdc.c b/drivers/net/wireless/bcmdhd/dhd_cdc.c
index 3a4de96..d01853c 100644
--- a/drivers/net/wireless/bcmdhd/dhd_cdc.c
+++ b/drivers/net/wireless/bcmdhd/dhd_cdc.c
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: dhd_cdc.c,v 1.51.6.31 2011-02-09 14:31:43 Exp $
+ * $Id: dhd_cdc.c 303389 2011-12-16 09:30:48Z $
*
* BDC is like CDC, except it includes a header for data packets to convey
* packet priority over the bus, and flags (e.g. to indicate checksum status
@@ -78,6 +78,8 @@
unsigned char buf[WLC_IOCTL_MAXLEN + ROUND_UP_MARGIN];
} dhd_prot_t;
+extern int dhd_dbus_txdata(dhd_pub_t *dhdp, void *pktbuf);
+
static int
dhdcdc_msg(dhd_pub_t *dhd)
{
@@ -2174,6 +2176,7 @@
WLFC_FLAGS_CREDIT_STATUS_SIGNALS |
WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE : 0;
+ dhd->wlfc_state = NULL;
/*
try to enable/disable signaling by sending "tlv" iovar. if that fails,
@@ -2460,10 +2463,10 @@
return 0;
fail:
-#ifndef DHD_USE_STATIC_BUF
+#ifndef CONFIG_DHD_USE_STATIC_BUF
if (cdc != NULL)
MFREE(dhd->osh, cdc, sizeof(dhd_prot_t));
-#endif
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
return BCME_NOMEM;
}
@@ -2474,9 +2477,9 @@
#ifdef PROP_TXSTATUS
dhd_wlfc_deinit(dhd);
#endif
-#ifndef DHD_USE_STATIC_BUF
+#ifndef CONFIG_DHD_USE_STATIC_BUF
MFREE(dhd->osh, dhd->prot, sizeof(dhd_prot_t));
-#endif
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
dhd->prot = NULL;
}
@@ -2512,9 +2515,10 @@
ret = dhd_wlfc_init(dhd);
#endif
-#if !defined(WL_CFG80211)
+#if defined(WL_CFG80211)
+ if (dhd_download_fw_on_driverload)
+#endif /* defined(WL_CFG80211) */
ret = dhd_preinit_ioctls(dhd);
-#endif /* WL_CFG80211 */
/* Always assumes wl for now */
dhd->iswl = TRUE;
diff --git a/drivers/net/wireless/bcmdhd/dhd_cfg80211.c b/drivers/net/wireless/bcmdhd/dhd_cfg80211.c
new file mode 100644
index 0000000..800590c
--- /dev/null
+++ b/drivers/net/wireless/bcmdhd/dhd_cfg80211.c
@@ -0,0 +1,593 @@
+/*
+ * Linux cfg80211 driver - Dongle Host Driver (DHD) related
+ *
+ * Copyright (C) 1999-2011, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: wl_cfg80211.c,v 1.1.4.1.2.14 2011/02/09 01:40:07 Exp $
+ */
+
+#include <net/rtnetlink.h>
+
+#include <bcmutils.h>
+#include <wldev_common.h>
+#include <wl_cfg80211.h>
+#include <dhd_cfg80211.h>
+extern struct wl_priv *wlcfg_drv_priv;
+static int dhd_dongle_up = FALSE;
+
+static s32 wl_dongle_up(struct net_device *ndev, u32 up);
+
+/**
+ * Function implementations
+ */
+
+s32 dhd_cfg80211_init(struct wl_priv *wl)
+{
+ dhd_dongle_up = FALSE;
+ return 0;
+}
+
+s32 dhd_cfg80211_deinit(struct wl_priv *wl)
+{
+ dhd_dongle_up = FALSE;
+ return 0;
+}
+
+s32 dhd_cfg80211_down(struct wl_priv *wl)
+{
+ dhd_dongle_up = FALSE;
+ return 0;
+}
+
+static s32 wl_dongle_up(struct net_device *ndev, u32 up)
+{
+ s32 err = 0;
+
+ err = wldev_ioctl(ndev, WLC_UP, &up, sizeof(up), true);
+ if (unlikely(err)) {
+ WL_ERR(("WLC_UP error (%d)\n", err));
+ }
+ return err;
+}
+s32 dhd_config_dongle(struct wl_priv *wl, bool need_lock)
+{
+#ifndef DHD_SDALIGN
+#define DHD_SDALIGN 32
+#endif
+ struct net_device *ndev;
+ s32 err = 0;
+
+ WL_TRACE(("In\n"));
+ if (dhd_dongle_up) {
+ WL_ERR(("Dongle is already up\n"));
+ return err;
+ }
+
+ ndev = wl_to_prmry_ndev(wl);
+
+ if (need_lock)
+ rtnl_lock();
+
+ err = wl_dongle_up(ndev, 0);
+ if (unlikely(err)) {
+ WL_ERR(("wl_dongle_up failed\n"));
+ goto default_conf_out;
+ }
+ dhd_dongle_up = true;
+
+default_conf_out:
+ if (need_lock)
+ rtnl_unlock();
+ return err;
+
+}
+
+
+/* TODO: clean up the BT-Coex code, it still have some legacy ioctl/iovar functions */
+#define COEX_DHCP
+
+#if defined(COEX_DHCP)
+
+/* use New SCO/eSCO smart YG suppression */
+#define BT_DHCP_eSCO_FIX
+/* this flag boost wifi pkt priority to max, caution: -not fair to sco */
+#define BT_DHCP_USE_FLAGS
+/* T1 start SCO/ESCo priority suppression */
+#define BT_DHCP_OPPR_WIN_TIME 2500
+/* T2 turn off SCO/SCO supperesion is (timeout) */
+#define BT_DHCP_FLAG_FORCE_TIME 5500
+
+enum wl_cfg80211_btcoex_status {
+ BT_DHCP_IDLE,
+ BT_DHCP_START,
+ BT_DHCP_OPPR_WIN,
+ BT_DHCP_FLAG_FORCE_TIMEOUT
+};
+
+/*
+ * get named driver variable to uint register value and return error indication
+ * calling example: dev_wlc_intvar_get_reg(dev, "btc_params",66, ®_value)
+ */
+static int
+dev_wlc_intvar_get_reg(struct net_device *dev, char *name,
+ uint reg, int *retval)
+{
+ union {
+ char buf[WLC_IOCTL_SMLEN];
+ int val;
+ } var;
+ int error;
+
+ bcm_mkiovar(name, (char *)(®), sizeof(reg),
+ (char *)(&var), sizeof(var.buf));
+ error = wldev_ioctl(dev, WLC_GET_VAR, (char *)(&var), sizeof(var.buf), false);
+
+ *retval = dtoh32(var.val);
+ return (error);
+}
+
+static int
+dev_wlc_bufvar_set(struct net_device *dev, char *name, char *buf, int len)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)
+ char ioctlbuf_local[1024];
+#else
+ static char ioctlbuf_local[1024];
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) */
+
+ bcm_mkiovar(name, buf, len, ioctlbuf_local, sizeof(ioctlbuf_local));
+
+ return (wldev_ioctl(dev, WLC_SET_VAR, ioctlbuf_local, sizeof(ioctlbuf_local), true));
+}
+/*
+get named driver variable to uint register value and return error indication
+calling example: dev_wlc_intvar_set_reg(dev, "btc_params",66, value)
+*/
+static int
+dev_wlc_intvar_set_reg(struct net_device *dev, char *name, char *addr, char * val)
+{
+ char reg_addr[8];
+
+ memset(reg_addr, 0, sizeof(reg_addr));
+ memcpy((char *)®_addr[0], (char *)addr, 4);
+ memcpy((char *)®_addr[4], (char *)val, 4);
+
+ return (dev_wlc_bufvar_set(dev, name, (char *)®_addr[0], sizeof(reg_addr)));
+}
+
+static bool btcoex_is_sco_active(struct net_device *dev)
+{
+ int ioc_res = 0;
+ bool res = FALSE;
+ int sco_id_cnt = 0;
+ int param27;
+ int i;
+
+ for (i = 0; i < 12; i++) {
+
+ ioc_res = dev_wlc_intvar_get_reg(dev, "btc_params", 27, ¶m27);
+
+ WL_TRACE(("%s, sample[%d], btc params: 27:%x\n",
+ __FUNCTION__, i, param27));
+
+ if (ioc_res < 0) {
+ WL_ERR(("%s ioc read btc params error\n", __FUNCTION__));
+ break;
+ }
+
+ if ((param27 & 0x6) == 2) { /* count both sco & esco */
+ sco_id_cnt++;
+ }
+
+ if (sco_id_cnt > 2) {
+ WL_TRACE(("%s, sco/esco detected, pkt id_cnt:%d samples:%d\n",
+ __FUNCTION__, sco_id_cnt, i));
+ res = TRUE;
+ break;
+ }
+
+ msleep(5);
+ }
+
+ return res;
+}
+
+#if defined(BT_DHCP_eSCO_FIX)
+/* Enhanced BT COEX settings for eSCO compatibility during DHCP window */
+static int set_btc_esco_params(struct net_device *dev, bool trump_sco)
+{
+ static bool saved_status = FALSE;
+
+ char buf_reg50va_dhcp_on[8] =
+ { 50, 00, 00, 00, 0x22, 0x80, 0x00, 0x00 };
+ char buf_reg51va_dhcp_on[8] =
+ { 51, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 };
+ char buf_reg64va_dhcp_on[8] =
+ { 64, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 };
+ char buf_reg65va_dhcp_on[8] =
+ { 65, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 };
+ char buf_reg71va_dhcp_on[8] =
+ { 71, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 };
+ uint32 regaddr;
+ static uint32 saved_reg50;
+ static uint32 saved_reg51;
+ static uint32 saved_reg64;
+ static uint32 saved_reg65;
+ static uint32 saved_reg71;
+
+ if (trump_sco) {
+ /* this should reduce eSCO agressive retransmit
+ * w/o breaking it
+ */
+
+ /* 1st save current */
+ WL_TRACE(("Do new SCO/eSCO coex algo {save &"
+ "override}\n"));
+ if ((!dev_wlc_intvar_get_reg(dev, "btc_params", 50, &saved_reg50)) &&
+ (!dev_wlc_intvar_get_reg(dev, "btc_params", 51, &saved_reg51)) &&
+ (!dev_wlc_intvar_get_reg(dev, "btc_params", 64, &saved_reg64)) &&
+ (!dev_wlc_intvar_get_reg(dev, "btc_params", 65, &saved_reg65)) &&
+ (!dev_wlc_intvar_get_reg(dev, "btc_params", 71, &saved_reg71))) {
+ saved_status = TRUE;
+ WL_TRACE(("%s saved bt_params[50,51,64,65,71]:"
+ "0x%x 0x%x 0x%x 0x%x 0x%x\n",
+ __FUNCTION__, saved_reg50, saved_reg51,
+ saved_reg64, saved_reg65, saved_reg71));
+ } else {
+ WL_ERR((":%s: save btc_params failed\n",
+ __FUNCTION__));
+ saved_status = FALSE;
+ return -1;
+ }
+
+ WL_TRACE(("override with [50,51,64,65,71]:"
+ "0x%x 0x%x 0x%x 0x%x 0x%x\n",
+ *(u32 *)(buf_reg50va_dhcp_on+4),
+ *(u32 *)(buf_reg51va_dhcp_on+4),
+ *(u32 *)(buf_reg64va_dhcp_on+4),
+ *(u32 *)(buf_reg65va_dhcp_on+4),
+ *(u32 *)(buf_reg71va_dhcp_on+4)));
+
+ dev_wlc_bufvar_set(dev, "btc_params",
+ (char *)&buf_reg50va_dhcp_on[0], 8);
+ dev_wlc_bufvar_set(dev, "btc_params",
+ (char *)&buf_reg51va_dhcp_on[0], 8);
+ dev_wlc_bufvar_set(dev, "btc_params",
+ (char *)&buf_reg64va_dhcp_on[0], 8);
+ dev_wlc_bufvar_set(dev, "btc_params",
+ (char *)&buf_reg65va_dhcp_on[0], 8);
+ dev_wlc_bufvar_set(dev, "btc_params",
+ (char *)&buf_reg71va_dhcp_on[0], 8);
+
+ saved_status = TRUE;
+ } else if (saved_status) {
+ /* restore previously saved bt params */
+ WL_TRACE(("Do new SCO/eSCO coex algo {save &"
+ "override}\n"));
+
+ regaddr = 50;
+ dev_wlc_intvar_set_reg(dev, "btc_params",
+ (char *)®addr, (char *)&saved_reg50);
+ regaddr = 51;
+ dev_wlc_intvar_set_reg(dev, "btc_params",
+ (char *)®addr, (char *)&saved_reg51);
+ regaddr = 64;
+ dev_wlc_intvar_set_reg(dev, "btc_params",
+ (char *)®addr, (char *)&saved_reg64);
+ regaddr = 65;
+ dev_wlc_intvar_set_reg(dev, "btc_params",
+ (char *)®addr, (char *)&saved_reg65);
+ regaddr = 71;
+ dev_wlc_intvar_set_reg(dev, "btc_params",
+ (char *)®addr, (char *)&saved_reg71);
+
+ WL_TRACE(("restore bt_params[50,51,64,65,71]:"
+ "0x%x 0x%x 0x%x 0x%x 0x%x\n",
+ saved_reg50, saved_reg51, saved_reg64,
+ saved_reg65, saved_reg71));
+
+ saved_status = FALSE;
+ } else {
+ WL_ERR((":%s att to restore not saved BTCOEX params\n",
+ __FUNCTION__));
+ return -1;
+ }
+ return 0;
+}
+#endif /* BT_DHCP_eSCO_FIX */
+
+static void
+wl_cfg80211_bt_setflag(struct net_device *dev, bool set)
+{
+#if defined(BT_DHCP_USE_FLAGS)
+ char buf_flag7_dhcp_on[8] = { 7, 00, 00, 00, 0x1, 0x0, 0x00, 0x00 };
+ char buf_flag7_default[8] = { 7, 00, 00, 00, 0x0, 0x00, 0x00, 0x00};
+#endif
+
+
+#if defined(BT_DHCP_eSCO_FIX)
+ /* set = 1, save & turn on 0 - off & restore prev settings */
+ set_btc_esco_params(dev, set);
+#endif
+
+#if defined(BT_DHCP_USE_FLAGS)
+ WL_TRACE(("WI-FI priority boost via bt flags, set:%d\n", set));
+ if (set == TRUE)
+ /* Forcing bt_flag7 */
+ dev_wlc_bufvar_set(dev, "btc_flags",
+ (char *)&buf_flag7_dhcp_on[0],
+ sizeof(buf_flag7_dhcp_on));
+ else
+ /* Restoring default bt flag7 */
+ dev_wlc_bufvar_set(dev, "btc_flags",
+ (char *)&buf_flag7_default[0],
+ sizeof(buf_flag7_default));
+#endif
+}
+
+static void wl_cfg80211_bt_timerfunc(ulong data)
+{
+ struct btcoex_info *bt_local = (struct btcoex_info *)data;
+ WL_TRACE(("%s\n", __FUNCTION__));
+ bt_local->timer_on = 0;
+ schedule_work(&bt_local->work);
+}
+
+static void wl_cfg80211_bt_handler(struct work_struct *work)
+{
+ struct btcoex_info *btcx_inf;
+
+ btcx_inf = container_of(work, struct btcoex_info, work);
+
+ if (btcx_inf->timer_on) {
+ btcx_inf->timer_on = 0;
+ del_timer_sync(&btcx_inf->timer);
+ }
+
+ switch (btcx_inf->bt_state) {
+ case BT_DHCP_START:
+ /* DHCP started
+ * provide OPPORTUNITY window to get DHCP address
+ */
+ WL_TRACE(("%s bt_dhcp stm: started \n",
+ __FUNCTION__));
+ btcx_inf->bt_state = BT_DHCP_OPPR_WIN;
+ mod_timer(&btcx_inf->timer,
+ jiffies + BT_DHCP_OPPR_WIN_TIME*HZ/1000);
+ btcx_inf->timer_on = 1;
+ break;
+
+ case BT_DHCP_OPPR_WIN:
+ if (btcx_inf->dhcp_done) {
+ WL_TRACE(("%s DHCP Done before T1 expiration\n",
+ __FUNCTION__));
+ goto btc_coex_idle;
+ }
+
+ /* DHCP is not over yet, start lowering BT priority
+ * enforce btc_params + flags if necessary
+ */
+ WL_TRACE(("%s DHCP T1:%d expired\n", __FUNCTION__,
+ BT_DHCP_OPPR_WIN_TIME));
+ if (btcx_inf->dev)
+ wl_cfg80211_bt_setflag(btcx_inf->dev, TRUE);
+ btcx_inf->bt_state = BT_DHCP_FLAG_FORCE_TIMEOUT;
+ mod_timer(&btcx_inf->timer,
+ jiffies + BT_DHCP_FLAG_FORCE_TIME*HZ/1000);
+ btcx_inf->timer_on = 1;
+ break;
+
+ case BT_DHCP_FLAG_FORCE_TIMEOUT:
+ if (btcx_inf->dhcp_done) {
+ WL_TRACE(("%s DHCP Done before T2 expiration\n",
+ __FUNCTION__));
+ } else {
+ /* Noo dhcp during T1+T2, restore BT priority */
+ WL_TRACE(("%s DHCP wait interval T2:%d"
+ "msec expired\n", __FUNCTION__,
+ BT_DHCP_FLAG_FORCE_TIME));
+ }
+
+ /* Restoring default bt priority */
+ if (btcx_inf->dev)
+ wl_cfg80211_bt_setflag(btcx_inf->dev, FALSE);
+btc_coex_idle:
+ btcx_inf->bt_state = BT_DHCP_IDLE;
+ btcx_inf->timer_on = 0;
+ break;
+
+ default:
+ WL_ERR(("%s error g_status=%d !!!\n", __FUNCTION__,
+ btcx_inf->bt_state));
+ if (btcx_inf->dev)
+ wl_cfg80211_bt_setflag(btcx_inf->dev, FALSE);
+ btcx_inf->bt_state = BT_DHCP_IDLE;
+ btcx_inf->timer_on = 0;
+ break;
+ }
+
+ net_os_wake_unlock(btcx_inf->dev);
+}
+
+int wl_cfg80211_btcoex_init(struct wl_priv *wl)
+{
+ struct btcoex_info *btco_inf = NULL;
+
+ btco_inf = kmalloc(sizeof(struct btcoex_info), GFP_KERNEL);
+ if (!btco_inf)
+ return -ENOMEM;
+
+ btco_inf->bt_state = BT_DHCP_IDLE;
+ btco_inf->ts_dhcp_start = 0;
+ btco_inf->ts_dhcp_ok = 0;
+ /* Set up timer for BT */
+ btco_inf->timer_ms = 10;
+ init_timer(&btco_inf->timer);
+ btco_inf->timer.data = (ulong)btco_inf;
+ btco_inf->timer.function = wl_cfg80211_bt_timerfunc;
+
+ btco_inf->dev = wl->wdev->netdev;
+
+ INIT_WORK(&btco_inf->work, wl_cfg80211_bt_handler);
+
+ wl->btcoex_info = btco_inf;
+ return 0;
+}
+
+void wl_cfg80211_btcoex_deinit(struct wl_priv *wl)
+{
+ if (!wl->btcoex_info)
+ return;
+
+ if (!wl->btcoex_info->timer_on) {
+ wl->btcoex_info->timer_on = 0;
+ del_timer_sync(&wl->btcoex_info->timer);
+ }
+
+ cancel_work_sync(&wl->btcoex_info->work);
+
+ kfree(wl->btcoex_info);
+ wl->btcoex_info = NULL;
+}
+#endif
+
+int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, char *command)
+{
+
+ struct wl_priv *wl = wlcfg_drv_priv;
+ char powermode_val = 0;
+ char buf_reg66va_dhcp_on[8] = { 66, 00, 00, 00, 0x10, 0x27, 0x00, 0x00 };
+ char buf_reg41va_dhcp_on[8] = { 41, 00, 00, 00, 0x33, 0x00, 0x00, 0x00 };
+ char buf_reg68va_dhcp_on[8] = { 68, 00, 00, 00, 0x90, 0x01, 0x00, 0x00 };
+
+ uint32 regaddr;
+ static uint32 saved_reg66;
+ static uint32 saved_reg41;
+ static uint32 saved_reg68;
+ static bool saved_status = FALSE;
+
+#ifdef COEX_DHCP
+ char buf_flag7_default[8] = { 7, 00, 00, 00, 0x0, 0x00, 0x00, 0x00};
+ struct btcoex_info *btco_inf = wl->btcoex_info;
+#endif /* COEX_DHCP */
+
+ /* Figure out powermode 1 or o command */
+ strncpy((char *)&powermode_val, command + strlen("BTCOEXMODE") +1, 1);
+
+ if (strnicmp((char *)&powermode_val, "1", strlen("1")) == 0) {
+
+ WL_TRACE(("%s: DHCP session starts\n", __FUNCTION__));
+
+ /* Retrieve and saved orig regs value */
+ if ((saved_status == FALSE) &&
+ (!dev_wlc_intvar_get_reg(dev, "btc_params", 66, &saved_reg66)) &&
+ (!dev_wlc_intvar_get_reg(dev, "btc_params", 41, &saved_reg41)) &&
+ (!dev_wlc_intvar_get_reg(dev, "btc_params", 68, &saved_reg68))) {
+ saved_status = TRUE;
+ WL_TRACE(("Saved 0x%x 0x%x 0x%x\n",
+ saved_reg66, saved_reg41, saved_reg68));
+
+ /* Disable PM mode during dhpc session */
+
+ /* Disable PM mode during dhpc session */
+#ifdef COEX_DHCP
+ /* Start BT timer only for SCO connection */
+ if (btcoex_is_sco_active(dev)) {
+ /* btc_params 66 */
+ dev_wlc_bufvar_set(dev, "btc_params",
+ (char *)&buf_reg66va_dhcp_on[0],
+ sizeof(buf_reg66va_dhcp_on));
+ /* btc_params 41 0x33 */
+ dev_wlc_bufvar_set(dev, "btc_params",
+ (char *)&buf_reg41va_dhcp_on[0],
+ sizeof(buf_reg41va_dhcp_on));
+ /* btc_params 68 0x190 */
+ dev_wlc_bufvar_set(dev, "btc_params",
+ (char *)&buf_reg68va_dhcp_on[0],
+ sizeof(buf_reg68va_dhcp_on));
+ saved_status = TRUE;
+
+ btco_inf->bt_state = BT_DHCP_START;
+ btco_inf->timer_on = 1;
+ mod_timer(&btco_inf->timer, btco_inf->timer.expires);
+ WL_TRACE(("%s enable BT DHCP Timer\n",
+ __FUNCTION__));
+ }
+#endif /* COEX_DHCP */
+ }
+ else if (saved_status == TRUE) {
+ WL_ERR(("%s was called w/o DHCP OFF. Continue\n", __FUNCTION__));
+ }
+ }
+ else if (strnicmp((char *)&powermode_val, "2", strlen("2")) == 0) {
+
+
+ /* Restoring PM mode */
+
+#ifdef COEX_DHCP
+ /* Stop any bt timer because DHCP session is done */
+ WL_TRACE(("%s disable BT DHCP Timer\n", __FUNCTION__));
+ if (btco_inf->timer_on) {
+ btco_inf->timer_on = 0;
+ del_timer_sync(&btco_inf->timer);
+
+ if (btco_inf->bt_state != BT_DHCP_IDLE) {
+ /* need to restore original btc flags & extra btc params */
+ WL_TRACE(("%s bt->bt_state:%d\n",
+ __FUNCTION__, btco_inf->bt_state));
+ /* wake up btcoex thread to restore btlags+params */
+ schedule_work(&btco_inf->work);
+ }
+ }
+
+ /* Restoring btc_flag paramter anyway */
+ if (saved_status == TRUE)
+ dev_wlc_bufvar_set(dev, "btc_flags",
+ (char *)&buf_flag7_default[0], sizeof(buf_flag7_default));
+#endif /* COEX_DHCP */
+
+ /* Restore original values */
+ if (saved_status == TRUE) {
+ regaddr = 66;
+ dev_wlc_intvar_set_reg(dev, "btc_params",
+ (char *)®addr, (char *)&saved_reg66);
+ regaddr = 41;
+ dev_wlc_intvar_set_reg(dev, "btc_params",
+ (char *)®addr, (char *)&saved_reg41);
+ regaddr = 68;
+ dev_wlc_intvar_set_reg(dev, "btc_params",
+ (char *)®addr, (char *)&saved_reg68);
+
+ WL_TRACE(("restore regs {66,41,68} <- 0x%x 0x%x 0x%x\n",
+ saved_reg66, saved_reg41, saved_reg68));
+ }
+ saved_status = FALSE;
+
+ }
+ else {
+ WL_ERR(("%s Unkwown yet power setting, ignored\n",
+ __FUNCTION__));
+ }
+
+ snprintf(command, 3, "OK");
+
+ return (strlen("OK"));
+}
diff --git a/drivers/net/wireless/bcmdhd/dhd_cfg80211.h b/drivers/net/wireless/bcmdhd/dhd_cfg80211.h
new file mode 100644
index 0000000..8dab652
--- /dev/null
+++ b/drivers/net/wireless/bcmdhd/dhd_cfg80211.h
@@ -0,0 +1,42 @@
+/*
+ * Linux cfg80211 driver - Dongle Host Driver (DHD) related
+ *
+ * Copyright (C) 1999-2011, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: wl_cfg80211.c,v 1.1.4.1.2.14 2011/02/09 01:40:07 Exp $
+ */
+
+
+#ifndef __DHD_CFG80211__
+#define __DHD_CFG80211__
+
+#include <wl_cfg80211.h>
+#include <wl_cfgp2p.h>
+
+s32 dhd_cfg80211_init(struct wl_priv *wl);
+s32 dhd_cfg80211_deinit(struct wl_priv *wl);
+s32 dhd_cfg80211_down(struct wl_priv *wl);
+s32 dhd_config_dongle(struct wl_priv *wl, bool need_lock);
+
+int wl_cfg80211_btcoex_init(struct wl_priv *wl);
+void wl_cfg80211_btcoex_deinit(struct wl_priv *wl);
+
+#endif /* __DHD_CFG80211__ */
diff --git a/drivers/net/wireless/bcmdhd/dhd_common.c b/drivers/net/wireless/bcmdhd/dhd_common.c
index a29c2fa..a54c391 100644
--- a/drivers/net/wireless/bcmdhd/dhd_common.c
+++ b/drivers/net/wireless/bcmdhd/dhd_common.c
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: dhd_common.c 290546 2011-10-19 01:55:21Z $
+ * $Id: dhd_common.c 307573 2012-01-12 00:04:39Z $
*/
#include <typedefs.h>
#include <osl.h>
@@ -336,6 +336,11 @@
case IOV_SVAL(IOV_MSGLEVEL):
dhd_msg_level = int_val;
+#ifdef WL_CFG80211
+ /* Enable DHD and WL logs in oneshot */
+ if (dhd_msg_level & DHD_WL_VAL)
+ wl_cfg80211_enable_trace(dhd_msg_level);
+#endif
break;
case IOV_GVAL(IOV_BCMERRORSTR):
bcm_strncpy_s((char *)arg, len, bcmerrorstr(dhd_pub->bcmerror), BCME_STRLEN);
@@ -857,6 +862,8 @@
break;
case WLC_E_SCAN_COMPLETE:
+ case WLC_E_ASSOC_REQ_IE:
+ case WLC_E_ASSOC_RESP_IE:
case WLC_E_PMKID_CACHE:
DHD_EVENT(("MACEVENT: %s\n", event_name));
break;
@@ -1489,7 +1496,7 @@
return -1;
iov_len = bcm_mkiovar("arp_hostip", 0, 0, buf, buflen);
- retcode = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, buflen, TRUE, 0);
+ retcode = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, buflen, FALSE, 0);
if (retcode) {
DHD_TRACE(("%s: ioctl WLC_GET_VAR error %d\n",
@@ -1902,6 +1909,7 @@
if ((!dhd) && (!ssids_local)) {
DHD_ERROR(("%s error exit\n", __FUNCTION__));
err = -1;
+ return err;
}
if (dhd_check_ap_wfd_mode_set(dhd) == TRUE)
@@ -2155,14 +2163,14 @@
int
wl_iw_parse_ssid_list_tlv(char** list_str, wlc_ssid_t* ssid, int max, int *bytes_left)
{
- char* str = *list_str;
+ char* str;
int idx = 0;
if ((list_str == NULL) || (*list_str == NULL) || (*bytes_left < 0)) {
DHD_ERROR(("%s error paramters\n", __FUNCTION__));
return -1;
}
-
+ str = *list_str;
while (*bytes_left > 0) {
if (str[0] != CSCAN_TLV_TYPE_SSID_IE) {
diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c
index 92cdc9b..233c891 100644
--- a/drivers/net/wireless/bcmdhd/dhd_linux.c
+++ b/drivers/net/wireless/bcmdhd/dhd_linux.c
@@ -22,7 +22,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: dhd_linux.c 291449 2011-10-22 12:16:26Z $
+ * $Id: dhd_linux.c 308879 2012-01-17 22:03:47Z $
*/
#include <typedefs.h>
@@ -109,6 +109,7 @@
#include <wl_android.h>
#ifdef ARP_OFFLOAD_SUPPORT
+void aoe_update_host_ipv4_table(dhd_pub_t *dhd_pub, u32 ipa, bool add);
static int dhd_device_event(struct notifier_block *this,
unsigned long event,
void *ptr);
@@ -273,6 +274,10 @@
#ifdef CONFIG_HAS_EARLYSUSPEND
struct early_suspend early_suspend;
#endif /* CONFIG_HAS_EARLYSUSPEND */
+
+#ifdef ARP_OFFLOAD_SUPPORT
+ u32 pend_ipaddr;
+#endif /* ARP_OFFLOAD_SUPPORT */
} dhd_info_t;
/* Definitions to provide path to the firmware and nvram
@@ -281,6 +286,8 @@
char firmware_path[MOD_PARAM_PATHLEN];
char nvram_path[MOD_PARAM_PATHLEN];
+int op_mode = 0;
+module_param(op_mode, int, 0644);
extern int wl_control_wl_start(struct net_device *dev);
extern int net_os_send_hang_message(struct net_device *dev);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
@@ -353,19 +360,6 @@
module_param_string(iface_name, iface_name, IFNAMSIZ, 0);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
-#define DAEMONIZE(a) daemonize(a); \
- allow_signal(SIGKILL); \
- allow_signal(SIGTERM);
-#else /* Linux 2.4 (w/o preemption patch) */
-#define RAISE_RX_SOFTIRQ() \
- cpu_raise_softirq(smp_processor_id(), NET_RX_SOFTIRQ)
-#define DAEMONIZE(a) daemonize(); \
- do { if (a) \
- strncpy(current->comm, a, MIN(sizeof(current->comm), (strlen(a) + 1))); \
- } while (0);
-#endif /* LINUX_VERSION_CODE */
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
#define BLOCKABLE() (!in_atomic())
#else
#define BLOCKABLE() (!in_interrupt())
@@ -436,6 +430,9 @@
;
static void dhd_net_if_lock_local(dhd_info_t *dhd);
static void dhd_net_if_unlock_local(dhd_info_t *dhd);
+#if !defined(AP) && defined(WLP2P)
+static u32 dhd_concurrent_fw(dhd_pub_t *dhd);
+#endif
#ifdef WLMEDIA_HTSF
void htsf_update(dhd_info_t *dhd, void *data);
@@ -498,7 +495,7 @@
static struct notifier_block dhd_sleep_pm_notifier = {
.notifier_call = dhd_sleep_pm_callback,
- .priority = 0
+ .priority = 10
};
extern int register_pm_notifier(struct notifier_block *nb);
extern int unregister_pm_notifier(struct notifier_block *nb);
@@ -693,8 +690,9 @@
return DHD_BAD_IF;
}
-struct net_device * dhd_idx2net(struct dhd_pub *dhd_pub, int ifidx)
+struct net_device * dhd_idx2net(void *pub, int ifidx)
{
+ struct dhd_pub *dhd_pub = (struct dhd_pub *)pub;
struct dhd_info *dhd_info;
if (!dhd_pub || ifidx < 0 || ifidx >= DHD_MAX_IFS)
@@ -922,6 +920,7 @@
DHD_ERROR(("%s: set cur_etheraddr failed\n", dhd_ifname(&dhd->pub, ifidx)));
} else {
memcpy(dhd->iflist[ifidx]->net->dev_addr, addr, ETHER_ADDR_LEN);
+ memcpy(dhd->pub.mac.octet, addr, ETHER_ADDR_LEN);
}
return ret;
@@ -941,8 +940,9 @@
unsigned long flags;
#endif
+ if (!ifp || !ifp->info || !ifp->idx)
+ return;
ASSERT(ifp && ifp->info && ifp->idx); /* Virtual interfaces only */
-
dhd = ifp->info;
DHD_TRACE(("%s: idx %d, state %d\n", __FUNCTION__, ifp->idx, ifp->state));
@@ -977,7 +977,7 @@
#ifdef WL_CFG80211
if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211)
if (!wl_cfg80211_notify_ifadd(ifp->net, ifp->idx, ifp->bssidx,
- dhd_net_attach)) {
+ (void*)dhd_net_attach)) {
ifp->state = DHD_IF_NONE;
return;
}
@@ -1033,6 +1033,7 @@
ifp->set_multicast = FALSE;
if (ifp->net) {
free_netdev(ifp->net);
+ ifp->net = NULL;
}
dhd->iflist[ifp->idx] = NULL;
#ifdef SOFTAP
@@ -1134,7 +1135,7 @@
if (ifidx == DHD_BAD_IF)
return -1;
- ASSERT(&dhd->thr_sysioc_ctl.thr_pid >= 0);
+ ASSERT(dhd->thr_sysioc_ctl.thr_pid >= 0);
memcpy(&dhd->macvalue, sa->sa_data, ETHER_ADDR_LEN);
dhd->set_macaddress = TRUE;
up(&dhd->thr_sysioc_ctl.sema);
@@ -1152,7 +1153,7 @@
if (ifidx == DHD_BAD_IF)
return;
- ASSERT(&dhd->thr_sysioc_ctl.thr_pid >= 0);
+ ASSERT(dhd->thr_sysioc_ctl.thr_pid >= 0);
dhd->iflist[ifidx]->set_multicast = TRUE;
up(&dhd->thr_sysioc_ctl.sema);
}
@@ -1163,6 +1164,7 @@
{
dhd_info_t *di = (dhd_info_t *)(pub->info);
ASSERT(di != NULL);
+
spin_lock_bh(&di->wlfc_spinlock);
return 1;
}
@@ -1196,7 +1198,7 @@
}
/* Update multicast statistic */
- if (PKTLEN(dhdp->osh, pktbuf) >= ETHER_ADDR_LEN) {
+ if (PKTLEN(dhdp->osh, pktbuf) >= ETHER_HDR_LEN) {
uint8 *pktdata = (uint8 *)PKTDATA(dhdp->osh, pktbuf);
eh = (struct ether_header *)pktdata;
@@ -1204,6 +1206,9 @@
dhdp->tx_multicast++;
if (ntoh16(eh->ether_type) == ETHER_TYPE_802_1X)
atomic_inc(&dhd->pend_8021x_cnt);
+ } else {
+ PKTFREE(dhd->pub.osh, pktbuf, TRUE);
+ return BCME_ERROR;
}
/* Look into the packet and update the packet priority */
@@ -1397,7 +1402,7 @@
int i;
dhd_if_t *ifp;
wl_event_msg_t event;
- int tout = DHD_PACKET_TIMEOUT;
+ int tout = DHD_PACKET_TIMEOUT_MS;
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
@@ -1414,7 +1419,7 @@
PKTFREE(dhdp->osh, pktbuf, TRUE);
continue;
}
-
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
/* Dropping packets before registering net device to avoid kernel panic */
if (!ifp->net || ifp->net->reg_state != NETREG_REGISTERED ||
!dhd->pub.up) {
@@ -1423,6 +1428,7 @@
PKTFREE(dhdp->osh, pktbuf, TRUE);
continue;
}
+#endif
pnext = PKTNEXT(dhdp->osh, pktbuf);
PKTSETNEXT(wl->sh.osh, pktbuf, NULL);
@@ -1498,10 +1504,12 @@
&data);
wl_event_to_host_order(&event);
+ tout = DHD_EVENT_TIMEOUT_MS;
if (event.event_type == WLC_E_BTA_HCI_EVENT) {
dhd_bta_doevt(dhdp, data, event.datalen);
+ } else if (event.event_type == WLC_E_PFN_NET_FOUND) {
+ tout *= 2;
}
- tout = DHD_EVENT_TIMEOUT;
}
ASSERT(ifidx < DHD_MAX_IFS && dhd->iflist[ifidx]);
@@ -1588,8 +1596,10 @@
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
ifidx = dhd_net2idx(dhd, net);
- if (ifidx == DHD_BAD_IF)
+ if (ifidx == DHD_BAD_IF) {
+ DHD_ERROR(("%s: BAD_IF\n", __FUNCTION__));
return NULL;
+ }
ifp = dhd->iflist[ifidx];
ASSERT(dhd && ifp);
@@ -2029,7 +2039,7 @@
/* send to dongle only if we are not waiting for reload already */
if (dhd->pub.hang_was_sent) {
DHD_ERROR(("%s: HANG was sent up earlier\n", __FUNCTION__));
- DHD_OS_WAKE_LOCK_TIMEOUT_ENABLE(&dhd->pub, DHD_EVENT_TIMEOUT);
+ DHD_OS_WAKE_LOCK_TIMEOUT_ENABLE(&dhd->pub, DHD_EVENT_TIMEOUT_MS);
DHD_OS_WAKE_UNLOCK(&dhd->pub);
return OSL_ERROR(BCME_DONGLE_DOWN);
}
@@ -2038,6 +2048,7 @@
DHD_TRACE(("%s: ifidx %d, cmd 0x%04x\n", __FUNCTION__, ifidx, cmd));
if (ifidx == DHD_BAD_IF) {
+ DHD_ERROR(("%s: BAD IF\n", __FUNCTION__));
DHD_OS_WAKE_UNLOCK(&dhd->pub);
return -1;
}
@@ -2235,6 +2246,7 @@
#endif
for (i = 1; i < DHD_MAX_IFS; i++) {
+ dhd_net_if_lock_local(dhd);
if (dhd->iflist[i]) {
DHD_TRACE(("Deleting IF: %d \n", i));
if ((dhd->iflist[i]->state != DHD_IF_DEL) &&
@@ -2244,6 +2256,7 @@
dhd_op_if(dhd->iflist[i]);
}
}
+ dhd_net_if_unlock_local(dhd);
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
@@ -2261,7 +2274,7 @@
int ifidx;
dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net);
DHD_OS_WAKE_LOCK(&dhd->pub);
- DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+ DHD_TRACE(("%s: Enter %p\n", __FUNCTION__, net));
if (dhd->pub.up == 0) {
goto exit;
}
@@ -2269,7 +2282,7 @@
#ifdef WL_CFG80211
if (ifidx == 0) {
- wl_cfg80211_down();
+ wl_cfg80211_down(NULL);
/*
* For CFG80211: Clean up all the left over virtual interfaces
@@ -2296,7 +2309,6 @@
if (ifidx == 0 && !dhd_download_fw_on_driverload)
wl_android_wifi_off(net);
#endif
- dhd->pub.hang_was_sent = 0;
dhd->pub.rxcnt_timeout = 0;
dhd->pub.txcnt_timeout = 0;
OLD_MOD_DEC_USE_COUNT;
@@ -2325,13 +2337,20 @@
firmware_path[0] = '\0';
}
+ dhd->pub.hang_was_sent = 0;
+
#if !defined(WL_CFG80211)
/*
* Force start if ifconfig_up gets called before START command
* We keep WEXT's wl_control_wl_start to provide backward compatibility
* This should be removed in the future
*/
- wl_control_wl_start(net);
+ ret = wl_control_wl_start(net);
+ if (ret != 0) {
+ DHD_ERROR(("%s: failed with code %d\n", __FUNCTION__, ret));
+ ret = -1;
+ goto exit;
+ }
#endif
ifidx = dhd_net2idx(dhd, net);
@@ -2353,12 +2372,17 @@
atomic_set(&dhd->pend_8021x_cnt, 0);
#if defined(WL_CFG80211)
DHD_ERROR(("\n%s\n", dhd_version));
- if (!dhd_download_fw_on_driverload)
- wl_android_wifi_on(net);
+ if (!dhd_download_fw_on_driverload) {
+ ret = wl_android_wifi_on(net);
+ if (ret != 0) {
+ DHD_ERROR(("%s: failed with code %d\n", __FUNCTION__, ret));
+ ret = -1;
+ goto exit;
+ }
+ }
#endif /* defined(WL_CFG80211) */
if (dhd->pub.busstate != DHD_BUS_DATA) {
- int ret;
/* try to bring up bus */
if ((ret = dhd_bus_start(&dhd->pub)) != 0) {
@@ -2381,7 +2405,7 @@
#endif /* TOE */
#if defined(WL_CFG80211)
- if (unlikely(wl_cfg80211_up())) {
+ if (unlikely(wl_cfg80211_up(NULL))) {
DHD_ERROR(("%s: failed to bring up cfg80211\n", __FUNCTION__));
ret = -1;
goto exit;
@@ -2403,6 +2427,32 @@
return ret;
}
+int dhd_do_driver_init(struct net_device *net)
+{
+ dhd_info_t *dhd = NULL;
+
+ if (!net) {
+ DHD_ERROR(("Primary Interface not initialized \n"));
+ return -EINVAL;
+ }
+
+ dhd = *(dhd_info_t **)netdev_priv(net);
+
+ /* If driver is already initialized, do nothing
+ */
+ if (dhd->pub.busstate == DHD_BUS_DATA) {
+ DHD_TRACE(("Driver already Inititalized. Nothing to do"));
+ return 0;
+ }
+
+ if (dhd_open(net) < 0) {
+ DHD_ERROR(("Driver Init Failed \n"));
+ return -1;
+ }
+
+ return 0;
+}
+
osl_t *
dhd_osl_attach(void *pdev, uint bustype)
{
@@ -2456,7 +2506,7 @@
ifp->state = DHD_IF_ADD;
ifp->idx = ifidx;
ifp->bssidx = bssidx;
- ASSERT(&dhd->thr_sysioc_ctl.thr_pid >= 0);
+ ASSERT(dhd->thr_sysioc_ctl.thr_pid >= 0);
up(&dhd->thr_sysioc_ctl.sema);
} else
ifp->net = (struct net_device *)handle;
@@ -2480,10 +2530,30 @@
ifp->state = DHD_IF_DEL;
ifp->idx = ifidx;
- ASSERT(&dhd->thr_sysioc_ctl.thr_pid >= 0);
+ ASSERT(dhd->thr_sysioc_ctl.thr_pid >= 0);
up(&dhd->thr_sysioc_ctl.sema);
}
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31))
+static struct net_device_ops dhd_ops_pri = {
+ .ndo_open = dhd_open,
+ .ndo_stop = dhd_stop,
+ .ndo_get_stats = dhd_get_stats,
+ .ndo_do_ioctl = dhd_ioctl_entry,
+ .ndo_start_xmit = dhd_start_xmit,
+ .ndo_set_mac_address = dhd_set_mac_address,
+ .ndo_set_multicast_list = dhd_set_multicast_list,
+};
+
+static struct net_device_ops dhd_ops_virt = {
+ .ndo_get_stats = dhd_get_stats,
+ .ndo_do_ioctl = dhd_ioctl_entry,
+ .ndo_start_xmit = dhd_start_xmit,
+ .ndo_set_mac_address = dhd_set_mac_address,
+ .ndo_set_multicast_list = dhd_set_multicast_list,
+};
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)) */
+
dhd_pub_t *
dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
{
@@ -2676,6 +2746,7 @@
#endif
#ifdef ARP_OFFLOAD_SUPPORT
+ dhd->pend_ipaddr = 0;
register_inetaddr_notifier(&dhd_notifier);
#endif /* ARP_OFFLOAD_SUPPORT */
@@ -2709,7 +2780,8 @@
DHD_TRACE(("Enter %s:\n", __FUNCTION__));
#ifdef DHDTHREAD
- dhd_os_sdlock(dhdp);
+ if (dhd->threads_only)
+ dhd_os_sdlock(dhdp);
#endif /* DHDTHREAD */
/* try to download image and nvram to the dongle */
@@ -2722,14 +2794,16 @@
DHD_ERROR(("%s: dhdsdio_probe_download failed. firmware = %s nvram = %s\n",
__FUNCTION__, fw_path, nv_path));
#ifdef DHDTHREAD
- dhd_os_sdunlock(dhdp);
+ if (dhd->threads_only)
+ dhd_os_sdunlock(dhdp);
#endif /* DHDTHREAD */
return -1;
}
}
if (dhd->pub.busstate != DHD_BUS_LOAD) {
#ifdef DHDTHREAD
- dhd_os_sdunlock(dhdp);
+ if (dhd->threads_only)
+ dhd_os_sdunlock(dhdp);
#endif /* DHDTHREAD */
return -ENETDOWN;
}
@@ -2743,7 +2817,8 @@
DHD_ERROR(("%s, dhd_bus_init failed %d\n", __FUNCTION__, ret));
#ifdef DHDTHREAD
- dhd_os_sdunlock(dhdp);
+ if (dhd->threads_only)
+ dhd_os_sdunlock(dhdp);
#endif /* DHDTHREAD */
return ret;
}
@@ -2759,7 +2834,8 @@
DHD_ERROR(("%s Host failed to register for OOB\n", __FUNCTION__));
#ifdef DHDTHREAD
- dhd_os_sdunlock(dhdp);
+ if (dhd->threads_only)
+ dhd_os_sdunlock(dhdp);
#endif /* DHDTHREAD */
return -ENODEV;
}
@@ -2776,13 +2852,15 @@
del_timer_sync(&dhd->timer);
DHD_ERROR(("%s failed bus is not ready\n", __FUNCTION__));
#ifdef DHDTHREAD
- dhd_os_sdunlock(dhdp);
+ if (dhd->threads_only)
+ dhd_os_sdunlock(dhdp);
#endif /* DHDTHREAD */
return -ENODEV;
}
#ifdef DHDTHREAD
- dhd_os_sdunlock(dhdp);
+ if (dhd->threads_only)
+ dhd_os_sdunlock(dhdp);
#endif /* DHDTHREAD */
#ifdef READ_MACADDR
@@ -2797,9 +2875,49 @@
dhd_write_macaddr(dhd->pub.mac.octet);
#endif
+#ifdef ARP_OFFLOAD_SUPPORT
+ if (dhd->pend_ipaddr) {
+#ifdef AOE_IP_ALIAS_SUPPORT
+ aoe_update_host_ipv4_table(&dhd->pub, dhd->pend_ipaddr, TRUE);
+#endif /* AOE_IP_ALIAS_SUPPORT */
+ dhd->pend_ipaddr = 0;
+ }
+#endif /* ARP_OFFLOAD_SUPPORT */
+
return 0;
}
+#if !defined(AP) && defined(WLP2P)
+/* For Android ICS MR2 release, the concurrent mode is enabled by default and the firmware
+ * name would be fw_bcmdhd.bin. So we need to determine whether P2P is enabled in the STA
+ * firmware and accordingly enable concurrent mode (Apply P2P settings). SoftAP firmware
+ * would still be named as fw_bcmdhd_apsta.
+ */
+static u32
+dhd_concurrent_fw(dhd_pub_t *dhd)
+{
+ int ret = 0;
+ char buf[WLC_IOCTL_SMLEN];
+
+ if ((!op_mode) && (strstr(fw_path, "_p2p") == NULL) &&
+ (strstr(fw_path, "_apsta") == NULL)) {
+ /* Given path is for the STA firmware. Check whether P2P support is present in
+ * the firmware. If so, set mode as P2P (concurrent support).
+ */
+ memset(buf, 0, sizeof(buf));
+ bcm_mkiovar("p2p", 0, 0, buf, sizeof(buf));
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf),
+ FALSE, 0)) < 0) {
+ DHD_TRACE(("%s: Get P2P failed (error=%d)\n", __FUNCTION__, ret));
+ } else if (buf[0] == 1) {
+ DHD_TRACE(("%s: P2P is supported\n", __FUNCTION__));
+ return 1;
+ }
+ }
+ return 0;
+}
+#endif
+
int
dhd_preinit_ioctls(dhd_pub_t *dhd)
{
@@ -2816,9 +2934,9 @@
#if defined(ARP_OFFLOAD_SUPPORT)
int arpoe = 1;
#endif
- int scan_assoc_time = 40;
+ int scan_assoc_time = DHD_SCAN_ACTIVE_TIME;
int scan_unassoc_time = 40;
- int scan_passive_time = 130;
+ int scan_passive_time = DHD_SCAN_PASSIVE_TIME;
char buf[WLC_IOCTL_SMLEN];
char *ptr;
uint32 listen_interval = LISTEN_INTERVAL; /* Default Listen Interval in Beacons */
@@ -2865,7 +2983,7 @@
#endif /* GET_CUSTOM_MAC_ENABLE */
#ifdef SET_RANDOM_MAC_SOFTAP
- if (strstr(fw_path, "_apsta") != NULL) {
+ if ((!op_mode && strstr(fw_path, "_apsta") != NULL) || (op_mode == 0x02)) {
uint rand_mac;
srandom32((uint)jiffies);
@@ -2889,7 +3007,8 @@
DHD_TRACE(("Firmware = %s\n", fw_path));
#if !defined(AP) && defined(WLP2P)
/* Check if firmware with WFD support used */
- if (strstr(fw_path, "_p2p") != NULL) {
+ if ((!op_mode && strstr(fw_path, "_p2p") != NULL) || (op_mode == 0x04) ||
+ (dhd_concurrent_fw(dhd))) {
bcm_mkiovar("apsta", (char *)&apsta, 4, iovbuf, sizeof(iovbuf));
if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR,
iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) {
@@ -2906,7 +3025,7 @@
#if !defined(AP) && defined(WL_CFG80211)
/* Check if firmware with HostAPD support used */
- if (strstr(fw_path, "_apsta") != NULL) {
+ if ((!op_mode && strstr(fw_path, "_apsta") != NULL) || (op_mode == 0x02)) {
/* Turn off MPC in AP mode */
bcm_mkiovar("mpc", (char *)&mpc, 4, iovbuf, sizeof(iovbuf));
if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
@@ -3016,6 +3135,8 @@
setbit(eventmask, WLC_E_LINK);
setbit(eventmask, WLC_E_NDIS_LINK);
setbit(eventmask, WLC_E_MIC_ERROR);
+ setbit(eventmask, WLC_E_ASSOC_REQ_IE);
+ setbit(eventmask, WLC_E_ASSOC_RESP_IE);
setbit(eventmask, WLC_E_PMKID_CACHE);
setbit(eventmask, WLC_E_TXFAIL);
setbit(eventmask, WLC_E_JOIN_START);
@@ -3136,26 +3257,6 @@
return ret;
}
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31))
-static struct net_device_ops dhd_ops_pri = {
- .ndo_open = dhd_open,
- .ndo_stop = dhd_stop,
- .ndo_get_stats = dhd_get_stats,
- .ndo_do_ioctl = dhd_ioctl_entry,
- .ndo_start_xmit = dhd_start_xmit,
- .ndo_set_mac_address = dhd_set_mac_address,
- .ndo_set_multicast_list = dhd_set_multicast_list,
-};
-
-static struct net_device_ops dhd_ops_virt = {
- .ndo_get_stats = dhd_get_stats,
- .ndo_do_ioctl = dhd_ioctl_entry,
- .ndo_start_xmit = dhd_start_xmit,
- .ndo_set_mac_address = dhd_set_mac_address,
- .ndo_set_multicast_list = dhd_set_multicast_list,
-};
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)) */
-
int dhd_change_mtu(dhd_pub_t *dhdp, int new_mtu, int ifidx)
{
struct dhd_info *dhd = dhdp->info;
@@ -3259,9 +3360,13 @@
DHD_ARPOE(("%s: [%s] Up IP: 0x%x\n",
__FUNCTION__, ifa->ifa_label, ifa->ifa_address));
- /* firmware not downloaded, do nothing */
- if (dhd->pub.busstate == DHD_BUS_DOWN) {
- DHD_ERROR(("%s: bus is down, exit\n", __FUNCTION__));
+ if (dhd->pub.busstate != DHD_BUS_DATA) {
+ DHD_ERROR(("%s: bus not ready, exit\n", __FUNCTION__));
+ if (dhd->pend_ipaddr) {
+ DHD_ERROR(("%s: overwrite pending ipaddr: 0x%x\n",
+ __FUNCTION__, dhd->pend_ipaddr));
+ }
+ dhd->pend_ipaddr = ifa->ifa_address;
break;
}
@@ -3279,7 +3384,7 @@
case NETDEV_DOWN:
DHD_ARPOE(("%s: [%s] Down IP: 0x%x\n",
__FUNCTION__, ifa->ifa_label, ifa->ifa_address));
-
+ dhd->pend_ipaddr = 0;
#ifdef AOE_IP_ALIAS_SUPPORT
if (!(ifa->ifa_label[strlen(ifa->ifa_label)-2] == 0x3a)) {
DHD_ARPOE(("%s: primary interface is down, AOE clr all\n",
@@ -3353,7 +3458,8 @@
* portable hotspot. This will not work in simultaneous AP/STA mode,
* nor with P2P. Need to set the Donlge's MAC address, and then use that.
*/
- if (ifidx > 0) {
+ if (!memcmp(temp_addr, dhd->iflist[0]->mac_addr,
+ ETHER_ADDR_LEN)) {
DHD_ERROR(("%s interface [%s]: set locally administered bit in MAC\n",
__func__, net->name));
temp_addr[0] |= 0x02;
@@ -3480,7 +3586,7 @@
}
#endif /* defined(CONFIG_WIRELESS_EXT) */
- if (&dhd->thr_sysioc_ctl.thr_pid >= 0) {
+ if (dhd->thr_sysioc_ctl.thr_pid >= 0) {
PROC_STOP(&dhd->thr_sysioc_ctl);
}
@@ -3490,13 +3596,15 @@
dhd_if_t *ifp;
/* Cleanup virtual interfaces */
- for (i = 1; i < DHD_MAX_IFS; i++)
+ for (i = 1; i < DHD_MAX_IFS; i++) {
+ dhd_net_if_lock_local(dhd);
if (dhd->iflist[i]) {
dhd->iflist[i]->state = DHD_IF_DEL;
dhd->iflist[i]->idx = i;
dhd_op_if(dhd->iflist[i]);
}
-
+ dhd_net_if_unlock_local(dhd);
+ }
/* delete primary interface 0 */
ifp = dhd->iflist[0];
ASSERT(ifp);
@@ -3547,7 +3655,7 @@
#ifdef WL_CFG80211
if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211) {
- wl_cfg80211_detach();
+ wl_cfg80211_detach(NULL);
dhd_monitor_uninit();
}
#endif
@@ -3594,7 +3702,6 @@
dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF);
}
-
static int __init
dhd_module_init(void)
{
@@ -3653,7 +3760,7 @@
}
#endif
#if defined(WL_CFG80211)
- error = wl_android_post_init();
+ wl_android_post_init();
#endif
return error;
@@ -3672,7 +3779,11 @@
return error;
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
late_initcall(dhd_module_init);
+#else
+module_init(dhd_module_init);
+#endif
module_exit(dhd_module_cleanup);
/*
@@ -3915,7 +4026,7 @@
dhd_os_sdunlock(pub);
}
-#if defined(DHD_USE_STATIC_BUF)
+#if defined(CONFIG_DHD_USE_STATIC_BUF)
uint8* dhd_os_prealloc(void *osh, int section, uint size)
{
return (uint8*)wl_android_prealloc(section, size);
@@ -3924,7 +4035,7 @@
void dhd_os_prefree(void *osh, void *addr, uint size)
{
}
-#endif /* defined(CONFIG_WIFI_CONTROL_FUNC) */
+#endif /* defined(CONFIG_DHD_USE_STATIC_BUF) */
#if defined(CONFIG_WIRELESS_EXT)
struct iw_statistics *
@@ -3973,7 +4084,13 @@
#endif /* defined(CONFIG_WIRELESS_EXT) */
#ifdef WL_CFG80211
-
+ if ((ntoh32(event->event_type) == WLC_E_IF) &&
+ (((dhd_if_event_t *)*data)->action == WLC_E_IF_ADD))
+ /* If ADD_IF has been called directly by wl utility then we
+ * should not report this. In case if ADD_IF was called from
+ * CFG stack, then too this event need not be reported back
+ */
+ return (BCME_OK);
if ((wl_cfg80211_is_progress_ifchange() ||
wl_cfg80211_is_progress_ifadd()) && (*ifidx != 0)) {
/*
@@ -4282,6 +4399,8 @@
#endif
#if defined(WL_CFG80211)
ret = wl_cfg80211_hang(dev, WLAN_REASON_UNSPECIFIED);
+ dev_close(dev);
+ dev_open(dev);
#endif
}
}
@@ -4421,7 +4540,7 @@
#ifdef CONFIG_HAS_WAKELOCK
if (dhd->wakelock_timeout_enable)
wake_lock_timeout(&dhd->wl_rxwake,
- dhd->wakelock_timeout_enable * HZ);
+ msecs_to_jiffies(dhd->wakelock_timeout_enable));
#endif
dhd->wakelock_timeout_enable = 0;
spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags);
@@ -4530,15 +4649,6 @@
return 0;
}
-int dhd_os_check_if_up(void *dhdp)
-{
- dhd_pub_t *pub = (dhd_pub_t *)dhdp;
-
- if (!pub)
- return 0;
- return pub->up;
-}
-
int net_os_wake_unlock(struct net_device *dev)
{
dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
@@ -4549,6 +4659,15 @@
return ret;
}
+int dhd_os_check_if_up(void *dhdp)
+{
+ dhd_pub_t *pub = (dhd_pub_t *)dhdp;
+
+ if (!pub)
+ return 0;
+ return pub->up;
+}
+
int dhd_ioctl_entry_local(struct net_device *net, wl_ioctl_t *ioc, int cmd)
{
int ifidx;
@@ -4588,8 +4707,8 @@
uint8 iftype, uint8* ea);
extern int dhd_wlfc_FIFOcreditmap_update(void* state, uint8* credits);
-int dhd_wlfc_interface_event(struct dhd_info *dhd, uint8 action, uint8 ifid, uint8 iftype,
- uint8* ea)
+int dhd_wlfc_interface_event(struct dhd_info *dhd,
+ ewlfc_mac_entry_action_t action, uint8 ifid, uint8 iftype, uint8* ea)
{
if (dhd->pub.wlfc_state == NULL)
return BCME_OK;
diff --git a/drivers/net/wireless/bcmdhd/dhd_sdio.c b/drivers/net/wireless/bcmdhd/dhd_sdio.c
index 2930115..d782316 100644
--- a/drivers/net/wireless/bcmdhd/dhd_sdio.c
+++ b/drivers/net/wireless/bcmdhd/dhd_sdio.c
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: dhd_sdio.c 288105 2011-10-06 01:58:02Z $
+ * $Id: dhd_sdio.c 309234 2012-01-19 01:44:16Z $
*/
#include <typedefs.h>
@@ -382,7 +382,7 @@
/* To check if there's window offered */
#define DATAOK(bus) \
- (((uint8)(bus->tx_max - bus->tx_seq) > 2) && \
+ (((uint8)(bus->tx_max - bus->tx_seq) > 1) && \
(((uint8)(bus->tx_max - bus->tx_seq) & 0x80) == 0))
/* To check if there's window offered for ctrl frame */
@@ -851,8 +851,10 @@
SBSDIO_FORCE_HW_CLKREQ_OFF, NULL);
/* Isolate the bus */
- bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
- SBSDIO_DEVCTL_PADS_ISO, NULL);
+ if (bus->sih->chip != BCM4329_CHIP_ID && bus->sih->chip != BCM4319_CHIP_ID) {
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
+ SBSDIO_DEVCTL_PADS_ISO, NULL);
+ }
/* Change state */
bus->sleeping = TRUE;
@@ -1366,9 +1368,7 @@
/* Send from dpc */
bus->ctrl_frame_buf = frame;
bus->ctrl_frame_len = len;
-
dhd_wait_for_event(bus->dhd, &bus->ctrl_frame_stat);
-
if (bus->ctrl_frame_stat == FALSE) {
DHD_INFO(("%s: ctrl_frame_stat == FALSE\n", __FUNCTION__));
ret = 0;
@@ -1520,7 +1520,7 @@
#ifdef DHD_DEBUG
IOV_CHECKDIED,
IOV_SERIALCONS,
-#endif
+#endif /* DHD_DEBUG */
IOV_DOWNLOAD,
IOV_SOCRAM_STATE,
IOV_FORCEEVEN,
@@ -2785,6 +2785,9 @@
uint retries;
int bcmerror = 0;
+ if (!bus->sih)
+ return BCME_ERROR;
+
/* To enter download state, disable ARM and reset SOCRAM.
* To exit download state, simply reset ARM (default is RAM boot).
*/
@@ -3565,7 +3568,7 @@
if ((uint8)(txmax - bus->tx_seq) > 0x40) {
DHD_ERROR(("%s: got unlikely tx max %d with tx_seq %d\n",
__FUNCTION__, txmax, bus->tx_seq));
- txmax = bus->tx_seq;
+ txmax = bus->tx_max;
}
bus->tx_max = txmax;
@@ -3766,6 +3769,14 @@
!bus->rxskip && rxleft && bus->dhd->busstate != DHD_BUS_DOWN;
rxseq++, rxleft--) {
+#ifdef DHDTHREAD
+ /* tx more to improve rx performance */
+ if ((bus->clkstate == CLK_AVAIL) && !bus->fcstate &&
+ pktq_mlen(&bus->txq, ~bus->flowcontrol) && DATAOK(bus)) {
+ dhdsdio_sendfromq(bus, dhd_txbound);
+ }
+#endif /* DHDTHREAD */
+
/* Handle glomming separately */
if (bus->glom || bus->glomd) {
uint8 cnt;
@@ -3986,7 +3997,7 @@
if ((uint8)(txmax - bus->tx_seq) > 0x40) {
DHD_ERROR(("%s: got unlikely tx max %d with tx_seq %d\n",
__FUNCTION__, txmax, bus->tx_seq));
- txmax = bus->tx_seq;
+ txmax = bus->tx_max;
}
bus->tx_max = txmax;
@@ -4143,7 +4154,7 @@
if ((uint8)(txmax - bus->tx_seq) > 0x40) {
DHD_ERROR(("%s: got unlikely tx max %d with tx_seq %d\n",
__FUNCTION__, txmax, bus->tx_seq));
- txmax = bus->tx_seq;
+ txmax = bus->tx_max;
}
bus->tx_max = txmax;
@@ -5183,16 +5194,17 @@
return TRUE;
if (chipid == BCM4319_CHIP_ID)
return TRUE;
- if (chipid == BCM4336_CHIP_ID)
- return TRUE;
if (chipid == BCM4330_CHIP_ID)
return TRUE;
+ if (chipid == BCM43239_CHIP_ID)
+ return TRUE;
+ if (chipid == BCM4336_CHIP_ID)
+ return TRUE;
if (chipid == BCM43237_CHIP_ID)
return TRUE;
if (chipid == BCM43362_CHIP_ID)
return TRUE;
- if (chipid == BCM43239_CHIP_ID)
- return TRUE;
+
return FALSE;
}
@@ -5369,6 +5381,7 @@
if (ret == BCME_NOTUP)
goto fail;
}
+
/* Ok, have the per-port tell the stack we're open for business */
if (dhd_net_attach(bus->dhd, 0) != 0) {
DHD_ERROR(("%s: Net attach failed!!\n", __FUNCTION__));
@@ -5545,8 +5558,10 @@
return TRUE;
fail:
- if (bus->sih != NULL)
+ if (bus->sih != NULL) {
si_detach(bus->sih);
+ bus->sih = NULL;
+ }
return FALSE;
}
@@ -5736,7 +5751,7 @@
return;
if (bus->rxbuf) {
-#ifndef DHD_USE_STATIC_BUF
+#ifndef CONFIG_DHD_USE_STATIC_BUF
MFREE(osh, bus->rxbuf, bus->rxblen);
#endif
bus->rxctl = bus->rxbuf = NULL;
@@ -5744,7 +5759,7 @@
}
if (bus->databuf) {
-#ifndef DHD_USE_STATIC_BUF
+#ifndef CONFIG_DHD_USE_STATIC_BUF
MFREE(osh, bus->databuf, MAX_DATA_BUF);
#endif
bus->databuf = NULL;
@@ -5779,6 +5794,7 @@
dhdsdio_clkctl(bus, CLK_NONE, FALSE);
}
si_detach(bus->sih);
+ bus->sih = NULL;
if (bus->vars && bus->varsz)
MFREE(osh, bus->vars, bus->varsz);
bus->vars = NULL;
diff --git a/drivers/net/wireless/bcmdhd/dhd_wlfc.h b/drivers/net/wireless/bcmdhd/dhd_wlfc.h
index 59d018b..c4d2518 100644
--- a/drivers/net/wireless/bcmdhd/dhd_wlfc.h
+++ b/drivers/net/wireless/bcmdhd/dhd_wlfc.h
@@ -18,7 +18,7 @@
* Notwithstanding the above, under no circumstances may you combine this
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
-* $Id: dhd_wlfc.h,v 1.1.8.1 2010-09-09 22:41:08 Exp $
+* $Id: dhd_wlfc.h 286994 2011-09-29 21:27:44Z $
*
*/
#ifndef __wlfc_host_driver_definitions_h__
@@ -201,6 +201,7 @@
#define WLFC_FCMODE_IMPLIED_CREDIT 1
#define WLFC_FCMODE_EXPLICIT_CREDIT 2
+/* How long to defer borrowing in milliseconds */
#define WLFC_BORROW_DEFER_PERIOD_MS 100
/* Mask to represent available ACs (note: BC/MC is ignored */
@@ -261,6 +262,15 @@
/* Timestamp to compute how long to defer borrowing for */
uint32 borrow_defer_timestamp;
+
} athost_wl_status_info_t;
+int dhd_wlfc_enable(dhd_pub_t *dhd);
+int dhd_wlfc_interface_event(struct dhd_info *,
+ ewlfc_mac_entry_action_t action, uint8 ifid, uint8 iftype, uint8* ea);
+int dhd_wlfc_FIFOcreditmap_event(struct dhd_info *dhd, uint8* event_data);
+int dhd_wlfc_event(struct dhd_info *dhd);
+int dhd_os_wlfc_block(dhd_pub_t *pub);
+int dhd_os_wlfc_unblock(dhd_pub_t *pub);
+
#endif /* __wlfc_host_driver_definitions_h__ */
diff --git a/drivers/net/wireless/bcmdhd/hndpmu.c b/drivers/net/wireless/bcmdhd/hndpmu.c
index b9586e4..0e49334 100644
--- a/drivers/net/wireless/bcmdhd/hndpmu.c
+++ b/drivers/net/wireless/bcmdhd/hndpmu.c
@@ -22,7 +22,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: hndpmu.c,v 1.228.2.56 2011-02-11 22:49:07 Exp $
+ * $Id: hndpmu.c,v 1.228.2.56 2011-02-11 22:49:07 $
*/
#include <typedefs.h>
@@ -93,26 +93,8 @@
{0, 0x1} };
/* SDIO Drive Strength to sel value table for PMU Rev 11 (1.2v) */
-static const sdiod_drive_str_t sdiod_drive_strength_tab4_1v2[] = {
- {16, 0x3},
- {13, 0x2},
- {11, 0x1},
- {8, 0x0},
- {6, 0x7},
- {4, 0x6},
- {2, 0x5},
- {0, 0x4} };
/* SDIO Drive Strength to sel value table for PMU Rev 11 (2.5v) */
-static const sdiod_drive_str_t sdiod_drive_strength_tab4_2v5[] = {
- {80, 0x5},
- {65, 0x4},
- {55, 0x7},
- {40, 0x6},
- {30, 0x1},
- {20, 0x0},
- {10, 0x3},
- {0, 0x2} };
/* SDIO Drive Strength to sel value table for PMU Rev 13 (1.8v) */
static const sdiod_drive_str_t sdiod_drive_strength_tab5_1v8[] = {
@@ -125,14 +107,6 @@
{0, 0x0} };
/* SDIO Drive Strength to sel value table for PMU Rev 13 (3.3v) */
-static const sdiod_drive_str_t sdiod_drive_strength_tab5_3v3[] = {
- {12, 0x7},
- {10, 0x6},
- {8, 0x5},
- {6, 0x4},
- {4, 0x2},
- {2, 0x1},
- {0, 0x0} };
#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu))
diff --git a/drivers/net/wireless/bcmdhd/include/Makefile b/drivers/net/wireless/bcmdhd/include/Makefile
index c07266f..67c4906 100644
--- a/drivers/net/wireless/bcmdhd/include/Makefile
+++ b/drivers/net/wireless/bcmdhd/include/Makefile
@@ -10,7 +10,7 @@
#
# Copyright 2005, Broadcom, Inc.
#
-# $Id: Makefile 241702 2011-02-19 00:41:03Z automrgr $
+# $Id: Makefile 241702 2011-02-19 00:41:03Z $
#
SRCBASE := ..
diff --git a/drivers/net/wireless/bcmdhd/include/aidmp.h b/drivers/net/wireless/bcmdhd/include/aidmp.h
index 375df44..b993a03 100644
--- a/drivers/net/wireless/bcmdhd/include/aidmp.h
+++ b/drivers/net/wireless/bcmdhd/include/aidmp.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: aidmp.h,v 13.4.14.1 2010-03-09 18:40:06 Exp $
+ * $Id: aidmp.h 277737 2011-08-16 17:54:59Z $
*/
diff --git a/drivers/net/wireless/bcmdhd/include/bcmcdc.h b/drivers/net/wireless/bcmdhd/include/bcmcdc.h
index ce45c50..77a20f8 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmcdc.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmcdc.h
@@ -24,7 +24,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: bcmcdc.h,v 13.25.10.3 2010-12-22 23:47:26 Exp $
+ * $Id: bcmcdc.h 277737 2011-08-16 17:54:59Z $
*/
#ifndef _bcmcdc_h_
diff --git a/drivers/net/wireless/bcmdhd/include/bcmdefs.h b/drivers/net/wireless/bcmdhd/include/bcmdefs.h
index da1fd5e..17cc0e9 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmdefs.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmdefs.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: bcmdefs.h,v 13.68.2.8 2011-01-08 04:04:19 Exp $
+ * $Id: bcmdefs.h 279282 2011-08-23 22:44:02Z $
*/
@@ -30,12 +30,26 @@
+
+#define BCM_REFERENCE(data) ((void)(data))
+
+
+
#define bcmreclaimed 0
#define _data _data
#define _fn _fn
+#define BCMPREATTACHDATA(_data) _data
+#define BCMPREATTACHFN(_fn) _fn
#define _data _data
#define _fn _fn
#define _fn _fn
+#define BCMNMIATTACHFN(_fn) _fn
+#define BCMNMIATTACHDATA(_data) _data
+#define BCMOVERLAY0DATA(_sym) _sym
+#define BCMOVERLAY0FN(_fn) _fn
+#define BCMOVERLAY1DATA(_sym) _sym
+#define BCMOVERLAY1FN(_fn) _fn
+#define BCMOVERLAYERRFN(_fn) _fn
#define CONST const
#define BCMFASTPATH
@@ -43,9 +57,30 @@
#define _data _data
+#define BCMROMDAT_NAME(_data) _data
#define _fn _fn
#define _fn _fn
#define STATIC static
+#define BCMROMDAT_ARYSIZ(data) ARRAYSIZE(data)
+#define BCMROMDAT_SIZEOF(data) sizeof(data)
+#define BCMROMDAT_APATCH(data)
+#define BCMROMDAT_SPATCH(data)
+
+
+
+#define OVERLAY_INLINE
+#define OSTATIC static
+#define BCMOVERLAYDATA(_ovly, _sym) _sym
+#define BCMOVERLAYFN(_ovly, _fn) _fn
+#define BCMOVERLAYERRFN(_fn) _fn
+#define BCMROMOVERLAYDATA(_ovly, _data) _data
+#define BCMROMOVERLAYFN(_ovly, _fn) _fn
+#define BCMATTACHOVERLAYDATA(_ovly, _sym) _sym
+#define BCMATTACHOVERLAYFN(_ovly, _fn) _fn
+#define BCMINITOVERLAYDATA(_ovly, _sym) _sym
+#define BCMINITOVERLAYFN(_ovly, _fn) _fn
+#define BCMUNINITOVERLAYFN(_ovly, _fn) _fn
+
#define SI_BUS 0
diff --git a/drivers/net/wireless/bcmdhd/include/bcmdevs.h b/drivers/net/wireless/bcmdhd/include/bcmdevs.h
index 4f707c0..ee01d8b 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmdevs.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmdevs.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: bcmdevs.h,v 13.285.2.39 2011-02-04 05:03:16 Exp $
+ * $Id: bcmdevs.h 295140 2011-11-09 17:22:01Z $
*/
@@ -31,7 +31,16 @@
#define VENDOR_EPIGRAM 0xfeda
#define VENDOR_BROADCOM 0x14e4
+#define VENDOR_3COM 0x10b7
+#define VENDOR_NETGEAR 0x1385
+#define VENDOR_DIAMOND 0x1092
+#define VENDOR_INTEL 0x8086
+#define VENDOR_DELL 0x1028
+#define VENDOR_HP 0x103c
+#define VENDOR_HP_COMPAQ 0x0e11
+#define VENDOR_APPLE 0x106b
#define VENDOR_SI_IMAGE 0x1095
+#define VENDOR_BUFFALO 0x1154
#define VENDOR_TI 0x104c
#define VENDOR_RICOH 0x1180
#define VENDOR_JMICRON 0x197b
@@ -54,9 +63,37 @@
#define BCM_DNGL_BL_PID_43239 0xbd1b
#define BCM_DNGL_BDC_PID 0x0bdc
#define BCM_DNGL_JTAG_PID 0x4a44
+
+
+#define BCM_HWUSB_PID_43239 43239
+
+
+#define BCM4210_DEVICE_ID 0x1072
+#define BCM4230_DEVICE_ID 0x1086
+#define BCM4401_ENET_ID 0x170c
+#define BCM3352_DEVICE_ID 0x3352
+#define BCM3360_DEVICE_ID 0x3360
+#define BCM4211_DEVICE_ID 0x4211
+#define BCM4231_DEVICE_ID 0x4231
+#define BCM4303_D11B_ID 0x4303
+#define BCM4311_D11G_ID 0x4311
+#define BCM4311_D11DUAL_ID 0x4312
+#define BCM4311_D11A_ID 0x4313
+#define BCM4328_D11DUAL_ID 0x4314
+#define BCM4328_D11G_ID 0x4315
+#define BCM4328_D11A_ID 0x4316
+#define BCM4318_D11G_ID 0x4318
+#define BCM4318_D11DUAL_ID 0x4319
+#define BCM4318_D11A_ID 0x431a
#define BCM4325_D11DUAL_ID 0x431b
#define BCM4325_D11G_ID 0x431c
#define BCM4325_D11A_ID 0x431d
+#define BCM4306_D11G_ID 0x4320
+#define BCM4306_D11A_ID 0x4321
+#define BCM4306_UART_ID 0x4322
+#define BCM4306_V90_ID 0x4323
+#define BCM4306_D11DUAL_ID 0x4324
+#define BCM4306_D11G_ID2 0x4325
#define BCM4321_D11N_ID 0x4328
#define BCM4321_D11N2G_ID 0x4329
#define BCM4321_D11N5G_ID 0x432a
@@ -98,17 +135,58 @@
#define BCM43237_D11N5G_ID 0x4356
#define BCM43227_D11N2G_ID 0x4358
#define BCM43228_D11N_ID 0x4359
-#define BCM43228_D11N5G_ID 0x435a
+#define BCM43228_D11N5G_ID 0x435a
#define BCM43362_D11N_ID 0x4363
#define BCM43239_D11N_ID 0x4370
+#define BCM4324_D11N_ID 0x4374
+#define BCM43217_D11N2G_ID 0x43a9
+#define BCM43131_D11N2G_ID 0x43aa
+#define BCM4314_D11N2G_ID 0x4364
+#define BCM43142_D11N2G_ID 0x4365
+#define BCMGPRS_UART_ID 0x4333
+#define BCMGPRS2_UART_ID 0x4344
+#define FPGA_JTAGM_ID 0x43f0
+#define BCM_JTAGM_ID 0x43f1
#define SDIOH_FPGA_ID 0x43f2
+#define BCM_SDIOH_ID 0x43f3
+#define SDIOD_FPGA_ID 0x43f4
#define SPIH_FPGA_ID 0x43f5
+#define BCM_SPIH_ID 0x43f6
+#define MIMO_FPGA_ID 0x43f8
+#define BCM_JTAGM2_ID 0x43f9
+#define SDHCI_FPGA_ID 0x43fa
+#define BCM4402_ENET_ID 0x4402
+#define BCM4402_V90_ID 0x4403
+#define BCM4410_DEVICE_ID 0x4410
+#define BCM4412_DEVICE_ID 0x4412
+#define BCM4430_DEVICE_ID 0x4430
+#define BCM4432_DEVICE_ID 0x4432
+#define BCM4704_ENET_ID 0x4706
#define BCM4710_DEVICE_ID 0x4710
+#define BCM47XX_AUDIO_ID 0x4711
+#define BCM47XX_V90_ID 0x4712
+#define BCM47XX_ENET_ID 0x4713
+#define BCM47XX_EXT_ID 0x4714
+#define BCM47XX_GMAC_ID 0x4715
+#define BCM47XX_USBH_ID 0x4716
+#define BCM47XX_USBD_ID 0x4717
+#define BCM47XX_IPSEC_ID 0x4718
+#define BCM47XX_ROBO_ID 0x4719
+#define BCM47XX_USB20H_ID 0x471a
+#define BCM47XX_USB20D_ID 0x471b
+#define BCM47XX_ATA100_ID 0x471d
+#define BCM47XX_SATAXOR_ID 0x471e
+#define BCM47XX_GIGETH_ID 0x471f
+#define BCM4712_MIPS_ID 0x4720
+#define BCM4716_DEVICE_ID 0x4722
+#define BCM47XX_SMBUS_EMU_ID 0x47fe
+#define BCM47XX_XOR_EMU_ID 0x47ff
+#define EPI41210_DEVICE_ID 0xa0fa
+#define EPI41230_DEVICE_ID 0xa10e
+#define JINVANI_SDIOH_ID 0x4743
#define BCM27XX_SDIOH_ID 0x2702
-#define PCIXX21_FLASHMEDIA0_ID 0x8033
-#define PCIXX21_SDIOH0_ID 0x8034
#define PCIXX21_FLASHMEDIA_ID 0x803b
#define PCIXX21_SDIOH_ID 0x803c
#define R5C822_SDIOH_ID 0x0822
@@ -121,11 +199,13 @@
#define BCM43112_CHIP_ID 43112
#define BCM4312_CHIP_ID 0x4312
#define BCM4313_CHIP_ID 0x4313
+#define BCM43131_CHIP_ID 43131
#define BCM4315_CHIP_ID 0x4315
#define BCM4318_CHIP_ID 0x4318
#define BCM4319_CHIP_ID 0x4319
#define BCM4320_CHIP_ID 0x4320
#define BCM4321_CHIP_ID 0x4321
+#define BCM43217_CHIP_ID 43217
#define BCM4322_CHIP_ID 0x4322
#define BCM43221_CHIP_ID 43221
#define BCM43222_CHIP_ID 43222
@@ -152,15 +232,28 @@
#define BCM4336_CHIP_ID 0x4336
#define BCM43362_CHIP_ID 43362
#define BCM4330_CHIP_ID 0x4330
+#define BCM6362_CHIP_ID 0x6362
+#define BCM4314_CHIP_ID 0x4314
+#define BCM43142_CHIP_ID 43142
+#define BCM4324_CHIP_ID 0x4324
+
+#define BCM4342_CHIP_ID 4342
#define BCM4402_CHIP_ID 0x4402
#define BCM4704_CHIP_ID 0x4704
#define BCM4710_CHIP_ID 0x4710
#define BCM4712_CHIP_ID 0x4712
+#define BCM4716_CHIP_ID 0x4716
+#define BCM47162_CHIP_ID 47162
+#define BCM4748_CHIP_ID 0x4748
+#define BCM4749_CHIP_ID 0x4749
#define BCM4785_CHIP_ID 0x4785
#define BCM5350_CHIP_ID 0x5350
#define BCM5352_CHIP_ID 0x5352
#define BCM5354_CHIP_ID 0x5354
#define BCM5365_CHIP_ID 0x5365
+#define BCM5356_CHIP_ID 0x5356
+#define BCM5357_CHIP_ID 0x5357
+#define BCM53572_CHIP_ID 53572
#define BCM4303_PKG_ID 2
@@ -175,8 +268,478 @@
#define BCM4329_289PIN_PKG_ID 0
#define BCM4329_182PIN_PKG_ID 1
#define BCM5354E_PKG_ID 1
+#define BCM4716_PKG_ID 8
+#define BCM4717_PKG_ID 9
+#define BCM4718_PKG_ID 10
+#define BCM5356_PKG_NONMODE 1
+#define BCM5358U_PKG_ID 8
+#define BCM5358_PKG_ID 9
+#define BCM47186_PKG_ID 10
+#define BCM5357_PKG_ID 11
+#define BCM5356U_PKG_ID 12
+#define BCM53572_PKG_ID 8
+#define BCM47188_PKG_ID 9
+#define BCM4331TT_PKG_ID 8
+#define BCM4331TN_PKG_ID 9
+#define BCM4331TNA0_PKG_ID 0xb
+
+
#define HDLSIM5350_PKG_ID 1
#define HDLSIM_PKG_ID 14
#define HWSIM_PKG_ID 15
+#define BCM43224_FAB_CSM 0x8
+#define BCM43224_FAB_SMIC 0xa
+#define BCM4336_WLBGA_PKG_ID 0x8
+#define BCM4330_WLBGA_PKG_ID 0x0
+#define BCM4314PCIE_ARM_PKG_ID (8 | 0)
+#define BCM4314SDIO_PKG_ID (8 | 1)
+#define BCM4314PCIE_PKG_ID (8 | 2)
+#define BCM4314SDIO_ARM_PKG_ID (8 | 3)
+#define BCM4314SDIO_FPBGA_PKG_ID (8 | 4)
+#define BCM4314DEV_PKG_ID (8 | 6)
+
+#define PCIXX21_FLASHMEDIA0_ID 0x8033
+#define PCIXX21_SDIOH0_ID 0x8034
+
+
+#define BFL_BTC2WIRE 0x00000001
+#define BFL_BTCOEX 0x00000001
+#define BFL_PACTRL 0x00000002
+#define BFL_AIRLINEMODE 0x00000004
+#define BFL_ADCDIV 0x00000008
+#define BFL_ENETROBO 0x00000010
+#define BFL_NOPLLDOWN 0x00000020
+#define BFL_CCKHIPWR 0x00000040
+#define BFL_ENETADM 0x00000080
+#define BFL_ENETVLAN 0x00000100
+#ifdef WLAFTERBURNER
+#define BFL_AFTERBURNER 0x00000200
+#endif
+#define BFL_NOPCI 0x00000400
+#define BFL_FEM 0x00000800
+#define BFL_EXTLNA 0x00001000
+#define BFL_HGPA 0x00002000
+#define BFL_BTC2WIRE_ALTGPIO 0x00004000
+#define BFL_ALTIQ 0x00008000
+#define BFL_NOPA 0x00010000
+#define BFL_RSSIINV 0x00020000
+#define BFL_PAREF 0x00040000
+#define BFL_3TSWITCH 0x00080000
+#define BFL_PHASESHIFT 0x00100000
+#define BFL_BUCKBOOST 0x00200000
+#define BFL_FEM_BT 0x00400000
+#define BFL_NOCBUCK 0x00800000
+#define BFL_CCKFAVOREVM 0x01000000
+#define BFL_PALDO 0x02000000
+#define BFL_LNLDO2_2P5 0x04000000
+#define BFL_FASTPWR 0x08000000
+#define BFL_UCPWRCTL_MININDX 0x08000000
+#define BFL_EXTLNA_5GHz 0x10000000
+#define BFL_TRSW_1by2 0x20000000
+#define BFL_LO_TRSW_R_5GHz 0x40000000
+#define BFL_ELNA_GAINDEF 0x80000000
+#define BFL_EXTLNA_TX 0x20000000
+
+
+#define BFL2_RXBB_INT_REG_DIS 0x00000001
+#define BFL2_APLL_WAR 0x00000002
+#define BFL2_TXPWRCTRL_EN 0x00000004
+#define BFL2_2X4_DIV 0x00000008
+#define BFL2_5G_PWRGAIN 0x00000010
+#define BFL2_PCIEWAR_OVR 0x00000020
+#define BFL2_CAESERS_BRD 0x00000040
+#define BFL2_BTC3WIRE 0x00000080
+#define BFL2_BTCLEGACY 0x00000080
+#define BFL2_SKWRKFEM_BRD 0x00000100
+#define BFL2_SPUR_WAR 0x00000200
+#define BFL2_GPLL_WAR 0x00000400
+#define BFL2_TRISTATE_LED 0x00000800
+#define BFL2_SINGLEANT_CCK 0x00001000
+#define BFL2_2G_SPUR_WAR 0x00002000
+#define BFL2_BPHY_ALL_TXCORES 0x00004000
+#define BFL2_FCC_BANDEDGE_WAR 0x00008000
+#define BFL2_GPLL_WAR2 0x00010000
+#define BFL2_IPALVLSHIFT_3P3 0x00020000
+#define BFL2_INTERNDET_TXIQCAL 0x00040000
+#define BFL2_XTALBUFOUTEN 0x00080000
+#define BFL2_ANAPACTRL_2G 0x00100000
+#define BFL2_ANAPACTRL_5G 0x00200000
+#define BFL2_ELNACTRL_TRSW_2G 0x00400000
+#define BFL2_BT_SHARE_ANT0 0x00800000
+#define BFL2_TEMPSENSE_HIGHER 0x01000000
+#define BFL2_BTC3WIREONLY 0x02000000
+#define BFL2_PWR_NOMINAL 0x04000000
+#define BFL2_EXTLNA_TX 0x08000000
+
+#define BFL2_4313_RADIOREG 0x10000000
+
+
+
+#define BOARD_GPIO_BTC3W_IN 0x850
+#define BOARD_GPIO_BTC3W_OUT 0x020
+#define BOARD_GPIO_BTCMOD_IN 0x010
+#define BOARD_GPIO_BTCMOD_OUT 0x020
+#define BOARD_GPIO_BTC_IN 0x080
+#define BOARD_GPIO_BTC_OUT 0x100
+#define BOARD_GPIO_PACTRL 0x200
+#define BOARD_GPIO_12 0x1000
+#define BOARD_GPIO_13 0x2000
+#define BOARD_GPIO_BTC4_IN 0x0800
+#define BOARD_GPIO_BTC4_BT 0x2000
+#define BOARD_GPIO_BTC4_STAT 0x4000
+#define BOARD_GPIO_BTC4_WLAN 0x8000
+#define BOARD_GPIO_1_WLAN_PWR 0x2
+#define BOARD_GPIO_4_WLAN_PWR 0x10
+
+#define GPIO_BTC4W_OUT_4312 0x010
+#define GPIO_BTC4W_OUT_43224 0x020
+#define GPIO_BTC4W_OUT_43224_SHARED 0x0e0
+#define GPIO_BTC4W_OUT_43225 0x0e0
+#define GPIO_BTC4W_OUT_43421 0x020
+#define GPIO_BTC4W_OUT_4313 0x060
+
+#define PCI_CFG_GPIO_SCS 0x10
+#define PCI_CFG_GPIO_HWRAD 0x20
+#define PCI_CFG_GPIO_XTAL 0x40
+#define PCI_CFG_GPIO_PLL 0x80
+
+
+#define PLL_DELAY 150
+#define FREF_DELAY 200
+#define MIN_SLOW_CLK 32
+#define XTAL_ON_DELAY 1000
+
+
+#define BU4710_BOARD 0x0400
+#define VSIM4710_BOARD 0x0401
+#define QT4710_BOARD 0x0402
+
+#define BU4309_BOARD 0x040a
+#define BCM94309CB_BOARD 0x040b
+#define BCM94309MP_BOARD 0x040c
+#define BCM4309AP_BOARD 0x040d
+
+#define BCM94302MP_BOARD 0x040e
+
+#define BU4306_BOARD 0x0416
+#define BCM94306CB_BOARD 0x0417
+#define BCM94306MP_BOARD 0x0418
+
+#define BCM94710D_BOARD 0x041a
+#define BCM94710R1_BOARD 0x041b
+#define BCM94710R4_BOARD 0x041c
+#define BCM94710AP_BOARD 0x041d
+
+#define BU2050_BOARD 0x041f
+
+#define BCM94306P50_BOARD 0x0420
+
+#define BCM94309G_BOARD 0x0421
+
+#define BU4704_BOARD 0x0423
+#define BU4702_BOARD 0x0424
+
+#define BCM94306PC_BOARD 0x0425
+
+#define MPSG4306_BOARD 0x0427
+
+#define BCM94702MN_BOARD 0x0428
+
+
+#define BCM94702CPCI_BOARD 0x0429
+
+
+#define BCM95380RR_BOARD 0x042a
+
+
+#define BCM94306CBSG_BOARD 0x042b
+
+
+#define PCSG94306_BOARD 0x042d
+
+
+#define BU4704SD_BOARD 0x042e
+
+
+#define BCM94704AGR_BOARD 0x042f
+
+
+#define BCM94308MP_BOARD 0x0430
+
+
+#define BCM94306GPRS_BOARD 0x0432
+
+
+#define BU5365_FPGA_BOARD 0x0433
+
+#define BU4712_BOARD 0x0444
+#define BU4712SD_BOARD 0x045d
+#define BU4712L_BOARD 0x045f
+
+
+#define BCM94712AP_BOARD 0x0445
+#define BCM94712P_BOARD 0x0446
+
+
+#define BU4318_BOARD 0x0447
+#define CB4318_BOARD 0x0448
+#define MPG4318_BOARD 0x0449
+#define MP4318_BOARD 0x044a
+#define SD4318_BOARD 0x044b
+
+
+#define BCM94313BU_BOARD 0x050f
+#define BCM94313HM_BOARD 0x0510
+#define BCM94313EPA_BOARD 0x0511
+#define BCM94313HMG_BOARD 0x051C
+
+
+#define BCM96338_BOARD 0x6338
+#define BCM96348_BOARD 0x6348
+#define BCM96358_BOARD 0x6358
+#define BCM96368_BOARD 0x6368
+
+
+#define BCM94306P_BOARD 0x044c
+
+
+#define BCM94303MP_BOARD 0x044e
+
+
+#define BCM94306MPSGH_BOARD 0x044f
+
+
+#define BCM94306MPM 0x0450
+#define BCM94306MPL 0x0453
+
+
+#define BCM94712AGR_BOARD 0x0451
+
+
+#define PC4303_BOARD 0x0454
+
+
+#define BCM95350K_BOARD 0x0455
+
+
+#define BCM95350R_BOARD 0x0456
+
+
+#define BCM94306MPLNA_BOARD 0x0457
+
+
+#define BU4320_BOARD 0x0458
+#define BU4320S_BOARD 0x0459
+#define BCM94320PH_BOARD 0x045a
+
+
+#define BCM94306MPH_BOARD 0x045b
+
+
+#define BCM94306PCIV_BOARD 0x045c
+
+#define BU4712SD_BOARD 0x045d
+
+#define BCM94320PFLSH_BOARD 0x045e
+
+#define BU4712L_BOARD 0x045f
+#define BCM94712LGR_BOARD 0x0460
+#define BCM94320R_BOARD 0x0461
+
+#define BU5352_BOARD 0x0462
+
+#define BCM94318MPGH_BOARD 0x0463
+
+#define BU4311_BOARD 0x0464
+#define BCM94311MC_BOARD 0x0465
+#define BCM94311MCAG_BOARD 0x0466
+
+#define BCM95352GR_BOARD 0x0467
+
+
+#define BCM95351AGR_BOARD 0x0470
+
+
+#define BCM94704MPCB_BOARD 0x0472
+
+
+#define BU4785_BOARD 0x0478
+
+
+#define BU4321_BOARD 0x046b
+#define BU4321E_BOARD 0x047c
+#define MP4321_BOARD 0x046c
+#define CB2_4321_BOARD 0x046d
+#define CB2_4321_AG_BOARD 0x0066
+#define MC4321_BOARD 0x046e
+
+
+#define BU4328_BOARD 0x0481
+#define BCM4328SDG_BOARD 0x0482
+#define BCM4328SDAG_BOARD 0x0483
+#define BCM4328UG_BOARD 0x0484
+#define BCM4328UAG_BOARD 0x0485
+#define BCM4328PC_BOARD 0x0486
+#define BCM4328CF_BOARD 0x0487
+
+
+#define BCM94325DEVBU_BOARD 0x0490
+#define BCM94325BGABU_BOARD 0x0491
+
+#define BCM94325SDGWB_BOARD 0x0492
+
+#define BCM94325SDGMDL_BOARD 0x04aa
+#define BCM94325SDGMDL2_BOARD 0x04c6
+#define BCM94325SDGMDL3_BOARD 0x04c9
+
+#define BCM94325SDABGWBA_BOARD 0x04e1
+
+
+#define BCM94322MC_SSID 0x04a4
+#define BCM94322USB_SSID 0x04a8
+#define BCM94322HM_SSID 0x04b0
+#define BCM94322USB2D_SSID 0x04bf
+
+
+#define BCM4312MCGSG_BOARD 0x04b5
+
+
+#define BCM94315DEVBU_SSID 0x04c2
+#define BCM94315USBGP_SSID 0x04c7
+#define BCM94315BGABU_SSID 0x04ca
+#define BCM94315USBGP41_SSID 0x04cb
+
+
+#define BCM94319DEVBU_SSID 0X04e5
+#define BCM94319USB_SSID 0X04e6
+#define BCM94319SD_SSID 0X04e7
+
+
+#define BCM94716NR2_SSID 0x04cd
+
+
+#define BCM94319DEVBU_SSID 0X04e5
+#define BCM94319USBNP4L_SSID 0X04e6
+#define BCM94319WLUSBN4L_SSID 0X04e7
+#define BCM94319SDG_SSID 0X04ea
+#define BCM94319LCUSBSDN4L_SSID 0X04eb
+#define BCM94319USBB_SSID 0x04ee
+#define BCM94319LCSDN4L_SSID 0X0507
+#define BCM94319LSUSBN4L_SSID 0X0508
+#define BCM94319SDNA4L_SSID 0X0517
+#define BCM94319SDELNA4L_SSID 0X0518
+#define BCM94319SDELNA6L_SSID 0X0539
+#define BCM94319ARCADYAN_SSID 0X0546
+#define BCM94319WINDSOR_SSID 0x0561
+#define BCM94319MLAP_SSID 0x0562
+#define BCM94319SDNA_SSID 0x058b
+#define BCM94319BHEMU3_SSID 0x0563
+#define BCM94319SDHMB_SSID 0x058c
+#define BCM94319SDBREF_SSID 0x05a1
+#define BCM94319USBSDB_SSID 0x05a2
+
+
+
+#define BCM94329AGB_SSID 0X04b9
+#define BCM94329TDKMDL1_SSID 0X04ba
+#define BCM94329TDKMDL11_SSID 0X04fc
+#define BCM94329OLYMPICN18_SSID 0X04fd
+#define BCM94329OLYMPICN90_SSID 0X04fe
+#define BCM94329OLYMPICN90U_SSID 0X050c
+#define BCM94329OLYMPICN90M_SSID 0X050b
+#define BCM94329AGBF_SSID 0X04ff
+#define BCM94329OLYMPICX17_SSID 0X0504
+#define BCM94329OLYMPICX17M_SSID 0X050a
+#define BCM94329OLYMPICX17U_SSID 0X0509
+#define BCM94329OLYMPICUNO_SSID 0X0564
+#define BCM94329MOTOROLA_SSID 0X0565
+#define BCM94329OLYMPICLOCO_SSID 0X0568
+
+#define BCM94336SD_WLBGABU_SSID 0x0511
+#define BCM94336SD_WLBGAREF_SSID 0x0519
+#define BCM94336SDGP_SSID 0x0538
+#define BCM94336SDG_SSID 0x0519
+#define BCM94336SDGN_SSID 0x0538
+#define BCM94336SDGFC_SSID 0x056B
+
+
+#define BCM94330SDG_SSID 0x0528
+#define BCM94330SD_FCBGABU_SSID 0x052e
+#define BCM94330SD_WLBGABU_SSID 0x052f
+#define BCM94330SD_FCBGA_SSID 0x0530
+#define BCM94330FCSDAGB_SSID 0x0532
+#define BCM94330OLYMPICAMG_SSID 0x0549
+#define BCM94330OLYMPICAMGEPA_SSID 0x054F
+#define BCM94330OLYMPICUNO3_SSID 0x0551
+#define BCM94330WLSDAGB_SSID 0x0547
+#define BCM94330CSPSDAGBB_SSID 0x054A
+
+
+#define BCM943224X21 0x056e
+#define BCM943224X21_FCC 0x00d1
+
+
+#define BCM943228BU8_SSID 0x0540
+#define BCM943228BU9_SSID 0x0541
+#define BCM943228BU_SSID 0x0542
+#define BCM943227HM4L_SSID 0x0543
+#define BCM943227HMB_SSID 0x0544
+#define BCM943228HM4L_SSID 0x0545
+#define BCM943228SD_SSID 0x0573
+
+
+#define BCM943239MOD_SSID 0x05ac
+#define BCM943239REF_SSID 0x05aa
+
+
+#define BCM94331X19 0x00D6
+#define BCM94331PCIEBT3Ax_SSID 0x00E4
+#define BCM94331X12_2G_SSID 0x00EC
+#define BCM94331X12_5G_SSID 0x00ED
+#define BCM94331X29B 0x00EF
+#define BCM94331BU_SSID 0x0523
+#define BCM94331S9BU_SSID 0x0524
+#define BCM94331MC_SSID 0x0525
+#define BCM94331MCI_SSID 0x0526
+#define BCM94331PCIEBT4_SSID 0x0527
+#define BCM94331HM_SSID 0x0574
+#define BCM94331PCIEDUAL_SSID 0x059B
+#define BCM94331MCH5_SSID 0x05A9
+#define BCM94331PCIEDUALV2_SSID 0x05B7
+#define BCM94331CS_SSID 0x05C6
+#define BCM94331CSAX_SSID 0x00EF
+
+
+#define BCM953572BU_SSID 0x058D
+#define BCM953572NR2_SSID 0x058E
+#define BCM947188NR2_SSID 0x058F
+#define BCM953572SDRNR2_SSID 0x0590
+
+
+#define BCM943236OLYMPICSULLEY_SSID 0x594
+#define BCM943236PREPROTOBLU2O3_SSID 0x5b9
+#define BCM943236USBELNA_SSID 0x5f8
+
+
+#define GPIO_NUMPINS 32
+
+
+#define RDL_RAM_BASE_4319 0x60000000
+#define RDL_RAM_BASE_4329 0x60000000
+#define RDL_RAM_SIZE_4319 0x48000
+#define RDL_RAM_SIZE_4329 0x48000
+#define RDL_RAM_SIZE_43236 0x70000
+#define RDL_RAM_BASE_43236 0x60000000
+#define RDL_RAM_SIZE_4328 0x60000
+#define RDL_RAM_BASE_4328 0x80000000
+#define RDL_RAM_SIZE_4322 0x60000
+#define RDL_RAM_BASE_4322 0x60000000
+
+
+#define MUXENAB_UART 0x00000001
+#define MUXENAB_GPIO 0x00000002
+#define MUXENAB_ERCX 0x00000004
+#define MUXENAB_JTAG 0x00000008
+#define MUXENAB_HOST_WAKE 0x00000010
#endif
diff --git a/drivers/net/wireless/bcmdhd/include/bcmendian.h b/drivers/net/wireless/bcmdhd/include/bcmendian.h
index 04b07ec..f3356a7 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmendian.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmendian.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: bcmendian.h,v 1.36 2009-11-09 05:29:43 Exp $
+ * $Id: bcmendian.h 277737 2011-08-16 17:54:59Z $
*
* This file by default provides proper behavior on little-endian architectures.
* On big-endian architectures, IL_BIGENDIAN should be defined.
diff --git a/drivers/net/wireless/bcmdhd/include/bcmpcispi.h b/drivers/net/wireless/bcmdhd/include/bcmpcispi.h
index fd148c5..51e0427 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmpcispi.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmpcispi.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: bcmpcispi.h,v 13.15.112.1 2010-11-15 18:22:12 Exp $
+ * $Id: bcmpcispi.h 277737 2011-08-16 17:54:59Z $
*/
#ifndef _BCM_PCI_SPI_H
#define _BCM_PCI_SPI_H
diff --git a/drivers/net/wireless/bcmdhd/include/bcmperf.h b/drivers/net/wireless/bcmdhd/include/bcmperf.h
index a3985cf..a503edb 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmperf.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmperf.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: bcmperf.h,v 13.5 2007-09-14 22:00:59 Exp $
+ * $Id: bcmperf.h 277737 2011-08-16 17:54:59Z $
*/
/* essai */
#ifndef _BCMPERF_H_
diff --git a/drivers/net/wireless/bcmdhd/include/bcmsdbus.h b/drivers/net/wireless/bcmdhd/include/bcmsdbus.h
index 5fda5e9..21a58b4 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmsdbus.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmsdbus.h
@@ -22,7 +22,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: bcmsdbus.h,v 13.17.86.2 2010-12-23 01:13:20 Exp $
+ * $Id: bcmsdbus.h 300017 2011-12-01 20:30:27Z $
*/
#ifndef _sdio_api_h_
@@ -117,4 +117,12 @@
+extern SDIOH_API_RC sdioh_sleep(sdioh_info_t *si, bool enab);
+
+/* GPIO support */
+extern SDIOH_API_RC sdioh_gpio_init(sdioh_info_t *sd);
+extern bool sdioh_gpioin(sdioh_info_t *sd, uint32 gpio);
+extern SDIOH_API_RC sdioh_gpioouten(sdioh_info_t *sd, uint32 gpio);
+extern SDIOH_API_RC sdioh_gpioout(sdioh_info_t *sd, uint32 gpio, bool enab);
+
#endif /* _sdio_api_h_ */
diff --git a/drivers/net/wireless/bcmdhd/include/bcmsdh.h b/drivers/net/wireless/bcmdhd/include/bcmsdh.h
index 6131d8a..def3c02 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmsdh.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmsdh.h
@@ -23,7 +23,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: bcmsdh.h,v 13.46.52.3 2010-10-19 00:41:44 Exp $
+ * $Id: bcmsdh.h 300017 2011-12-01 20:30:27Z $
*/
#ifndef _bcmsdh_h_
@@ -208,4 +208,12 @@
extern void bcmsdh_chipinfo(void *sdh, uint32 chip, uint32 chiprev);
+extern int bcmsdh_sleep(void *sdh, bool enab);
+
+/* GPIO support */
+extern int bcmsdh_gpio_init(void *sd);
+extern bool bcmsdh_gpioin(void *sd, uint32 gpio);
+extern int bcmsdh_gpioouten(void *sd, uint32 gpio);
+extern int bcmsdh_gpioout(void *sd, uint32 gpio, bool enab);
+
#endif /* _bcmsdh_h_ */
diff --git a/drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h b/drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h
index d188c4e..bea97b6 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: bcmsdh_sdmmc.h,v 13.5.88.1 2010-12-23 01:13:20 Exp $
+ * $Id: bcmsdh_sdmmc.h 277737 2011-08-16 17:54:59Z $
*/
#ifndef __BCMSDH_SDMMC_H__
diff --git a/drivers/net/wireless/bcmdhd/include/bcmsdpcm.h b/drivers/net/wireless/bcmdhd/include/bcmsdpcm.h
index ee29b5c..1b9d39f 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmsdpcm.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmsdpcm.h
@@ -22,7 +22,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: bcmsdpcm.h,v 13.4.90.2 2010-05-12 04:14:25 Exp $
+ * $Id: bcmsdpcm.h 277737 2011-08-16 17:54:59Z $
*/
#ifndef _bcmsdpcm_h_
diff --git a/drivers/net/wireless/bcmdhd/include/bcmsdspi.h b/drivers/net/wireless/bcmdhd/include/bcmsdspi.h
index 0bff355..a62bee4 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmsdspi.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmsdspi.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: bcmsdspi.h,v 13.11.86.1 2010-11-15 18:14:56 Exp $
+ * $Id: bcmsdspi.h 277737 2011-08-16 17:54:59Z $
*/
#ifndef _BCM_SD_SPI_H
#define _BCM_SD_SPI_H
diff --git a/drivers/net/wireless/bcmdhd/include/bcmsdstd.h b/drivers/net/wireless/bcmdhd/include/bcmsdstd.h
index 0f4c026..c14444c 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmsdstd.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmsdstd.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: bcmsdstd.h,v 13.21.2.6 2010-11-15 18:14:01 Exp $
+ * $Id: bcmsdstd.h 281604 2011-09-02 18:58:49Z $
*/
#ifndef _BCM_SD_STD_H
#define _BCM_SD_STD_H
@@ -78,6 +78,7 @@
#define SDIOH_CMD7_EXP_STATUS 0x00001E00
#define RETRIES_LARGE 100000
+#define sdstd_os_yield(sd) do {} while (0)
#define RETRIES_SMALL 100
@@ -148,8 +149,8 @@
bool got_hcint; /* local interrupt flag */
uint16 last_intrstatus; /* to cache intrstatus */
int host_UHSISupported; /* whether UHSI is supported for HC. */
- int card_UHSI_voltage_Supported; /* whether UHSI is supported for
- * Card in terms of Voltage [1.8 or 3.3].
+ int card_UHSI_voltage_Supported; /* whether UHSI is supported for
+ * Card in terms of Voltage [1.8 or 3.3].
*/
int global_UHSI_Supp; /* type of UHSI support in both host and card.
* HOST_SDR_UNSUPP: capabilities not supported/matched
@@ -171,21 +172,6 @@
#define USE_DMA(sd) ((bool)((sd->sd_dma_mode > 0) ? TRUE : FALSE))
-/* SDIO Host Control Register DMA Mode Definitions */
-#define SDIOH_SDMA_MODE 0
-#define SDIOH_ADMA1_MODE 1
-#define SDIOH_ADMA2_MODE 2
-#define SDIOH_ADMA2_64_MODE 3
-
-#define ADMA2_ATTRIBUTE_VALID (1 << 0) /* ADMA Descriptor line valid */
-#define ADMA2_ATTRIBUTE_END (1 << 1) /* End of Descriptor */
-#define ADMA2_ATTRIBUTE_INT (1 << 2) /* Interrupt when line is done */
-#define ADMA2_ATTRIBUTE_ACT_NOP (0 << 4) /* Skip current line, go to next. */
-#define ADMA2_ATTRIBUTE_ACT_RSV (1 << 4) /* Same as NOP */
-#define ADMA1_ATTRIBUTE_ACT_SET (1 << 4) /* ADMA1 Only - set transfer length */
-#define ADMA2_ATTRIBUTE_ACT_TRAN (2 << 4) /* Transfer Data of one descriptor line. */
-#define ADMA2_ATTRIBUTE_ACT_LINK (3 << 4) /* Link Descriptor */
-
/* States for Tuning and corr data */
#define TUNING_IDLE 0
#define TUNING_START 1
@@ -195,17 +181,6 @@
#define DATA_TRANSFER_IDLE 0
#define DATA_TRANSFER_ONGOING 1
-/* ADMA2 Descriptor Table Entry for 32-bit Address */
-typedef struct adma2_dscr_32b {
- uint32 len_attr;
- uint32 phys_addr;
-} adma2_dscr_32b_t;
-
-/* ADMA1 Descriptor Table Entry */
-typedef struct adma1_dscr {
- uint32 phys_addr_attr;
-} adma1_dscr_t;
-
/************************************************************
* Internal interfaces: per-port references into bcmsdstd.c
*/
@@ -254,6 +229,7 @@
extern bool sdstd_3_is_retuning_int_set(sdioh_info_t *sd);
extern bool sdstd_3_check_and_set_retuning(sdioh_info_t *sd);
extern int sdstd_3_get_tune_state(sdioh_info_t *sd);
+extern int sdstd_3_get_data_state(sdioh_info_t *sd);
extern void sdstd_3_set_tune_state(sdioh_info_t *sd, int state);
extern uint8 sdstd_3_get_tuning_exp(sdioh_info_t *sd);
extern uint32 sdstd_3_get_uhsi_clkmode(sdioh_info_t *sd);
diff --git a/drivers/net/wireless/bcmdhd/include/bcmspi.h b/drivers/net/wireless/bcmdhd/include/bcmspi.h
index 0eb2a30..34a02d0 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmspi.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmspi.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: bcmspi.h,v 13.5.112.1 2010-11-15 18:13:09 Exp $
+ * $Id: bcmspi.h 277737 2011-08-16 17:54:59Z $
*/
#ifndef _BCM_SPI_H
#define _BCM_SPI_H
diff --git a/drivers/net/wireless/bcmdhd/include/bcmutils.h b/drivers/net/wireless/bcmdhd/include/bcmutils.h
index 530036f..6849c26 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmutils.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmutils.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: bcmutils.h,v 13.236.2.16 2011-01-26 00:45:06 Exp $
+ * $Id: bcmutils.h 294991 2011-11-09 00:17:28Z $
*/
@@ -221,7 +221,9 @@
extern int pktpool_avail_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg);
extern int pktpool_empty_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg);
extern int pktpool_setmaxlen(pktpool_t *pktp, uint16 maxlen);
+extern int pktpool_setmaxlen_strict(osl_t *osh, pktpool_t *pktp, uint16 maxlen);
extern void pktpool_emptycb_disable(pktpool_t *pktp, bool disable);
+extern bool pktpool_emptycb_disabled(pktpool_t *pktp);
#define POOLPTR(pp) ((pktpool_t *)(pp))
#define pktpool_len(pp) (POOLPTR(pp)->len - 1)
@@ -330,6 +332,8 @@
extern void bcm_mdelay(uint ms);
+#define NVRAM_RECLAIM_CHECK(name)
+
extern char *getvar(char *vars, const char *name);
extern int getintvar(char *vars, const char *name);
extern int getintvararray(char *vars, const char *name, int index);
@@ -534,9 +538,17 @@
& ~((boundary) - 1))
#define ISPOWEROF2(x) ((((x)-1)&(x)) == 0)
#define VALID_MASK(mask) !((mask) & ((mask) + 1))
+
#ifndef OFFSETOF
+#ifdef __ARMCC_VERSION
+
+#include <stddef.h>
+#define OFFSETOF(type, member) offsetof(type, member)
+#else
#define OFFSETOF(type, member) ((uint)(uintptr)&((type *)0)->member)
#endif
+#endif
+
#ifndef ARRAYSIZE
#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
#endif
diff --git a/drivers/net/wireless/bcmdhd/include/bcmwifi.h b/drivers/net/wireless/bcmdhd/include/bcmwifi.h
index 45f3c03..e5207e9 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmwifi.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmwifi.h
@@ -23,7 +23,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: bcmwifi.h,v 1.29.6.3 2010-08-03 17:47:04 Exp $
+ * $Id: bcmwifi.h 277737 2011-08-16 17:54:59Z $
*/
diff --git a/drivers/net/wireless/bcmdhd/include/dhdioctl.h b/drivers/net/wireless/bcmdhd/include/dhdioctl.h
index 9661dac..0312d22 100644
--- a/drivers/net/wireless/bcmdhd/include/dhdioctl.h
+++ b/drivers/net/wireless/bcmdhd/include/dhdioctl.h
@@ -25,7 +25,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: dhdioctl.h,v 13.11.10.1 2010-12-22 23:47:26 Exp $
+ * $Id: dhdioctl.h 307573 2012-01-12 00:04:39Z $
*/
#ifndef _dhdioctl_h_
@@ -87,6 +87,7 @@
#define DHD_BTA_VAL 0x1000
#define DHD_ISCAN_VAL 0x2000
#define DHD_ARPOE_VAL 0x4000
+#define DHD_WL_VAL 0x8000
#ifdef SDTEST
/* For pktgen iovar */
diff --git a/drivers/net/wireless/bcmdhd/include/epivers.h b/drivers/net/wireless/bcmdhd/include/epivers.h
index ae1f975..53dd2f7 100644
--- a/drivers/net/wireless/bcmdhd/include/epivers.h
+++ b/drivers/net/wireless/bcmdhd/include/epivers.h
@@ -19,7 +19,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: epivers.h.in,v 13.32.4.1 2010-09-17 00:39:18 $
+ * $Id: epivers.h.in 277737 2011-08-16 17:54:59Z $
*
*/
@@ -31,19 +31,19 @@
#define EPI_MINOR_VERSION 90
-#define EPI_RC_NUMBER 125
+#define EPI_RC_NUMBER 195
-#define EPI_INCREMENTAL_NUMBER 94
+#define EPI_INCREMENTAL_NUMBER 23
#define EPI_BUILD_NUMBER 0
-#define EPI_VERSION 5, 90, 125, 94
+#define EPI_VERSION 5, 90, 195, 23
-#define EPI_VERSION_NUM 0x055a7d5e
+#define EPI_VERSION_NUM 0x055ac317
-#define EPI_VERSION_DEV 5.90.125
+#define EPI_VERSION_DEV 5.90.195
-#define EPI_VERSION_STR "5.90.125.94"
+#define EPI_VERSION_STR "5.90.195.23"
#endif
diff --git a/drivers/net/wireless/bcmdhd/include/hndpmu.h b/drivers/net/wireless/bcmdhd/include/hndpmu.h
index 51c51b9..69a834c 100644
--- a/drivers/net/wireless/bcmdhd/include/hndpmu.h
+++ b/drivers/net/wireless/bcmdhd/include/hndpmu.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: hndpmu.h,v 13.35.8.5 2011-02-11 00:56:32 Exp $
+ * $Id: hndpmu.h 277737 2011-08-16 17:54:59Z $
*/
#ifndef _hndpmu_h_
diff --git a/drivers/net/wireless/bcmdhd/include/hndrte_armtrap.h b/drivers/net/wireless/bcmdhd/include/hndrte_armtrap.h
index 8b9615c..7d862c4 100644
--- a/drivers/net/wireless/bcmdhd/include/hndrte_armtrap.h
+++ b/drivers/net/wireless/bcmdhd/include/hndrte_armtrap.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: hndrte_armtrap.h,v 13.4.14.1 2011-02-05 00:04:30 Exp $
+ * $Id: hndrte_armtrap.h 277737 2011-08-16 17:54:59Z $
*/
#ifndef _hndrte_armtrap_h
diff --git a/drivers/net/wireless/bcmdhd/include/hndrte_cons.h b/drivers/net/wireless/bcmdhd/include/hndrte_cons.h
index b9ede53..859ddc8 100644
--- a/drivers/net/wireless/bcmdhd/include/hndrte_cons.h
+++ b/drivers/net/wireless/bcmdhd/include/hndrte_cons.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: hndrte_cons.h,v 13.4.10.4 2011-02-05 00:08:20 Exp $
+ * $Id: hndrte_cons.h 277737 2011-08-16 17:54:59Z $
*/
#ifndef _HNDRTE_CONS_H
diff --git a/drivers/net/wireless/bcmdhd/include/hndsoc.h b/drivers/net/wireless/bcmdhd/include/hndsoc.h
index 4e26121..34f927c 100644
--- a/drivers/net/wireless/bcmdhd/include/hndsoc.h
+++ b/drivers/net/wireless/bcmdhd/include/hndsoc.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: hndsoc.h,v 13.11 2009-12-03 23:52:31 Exp $
+ * $Id: hndsoc.h 277737 2011-08-16 17:54:59Z $
*/
#ifndef _HNDSOC_H
diff --git a/drivers/net/wireless/bcmdhd/include/htsf.h b/drivers/net/wireless/bcmdhd/include/htsf.h
index 379fbbe..d875edb 100644
--- a/drivers/net/wireless/bcmdhd/include/htsf.h
+++ b/drivers/net/wireless/bcmdhd/include/htsf.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: htsf.h,v 1.1.2.4 2011-01-21 08:27:03 Exp $
+ * $Id: htsf.h 277737 2011-08-16 17:54:59Z $
*/
#ifndef _HTSF_H_
#define _HTSF_H_
diff --git a/drivers/net/wireless/bcmdhd/include/linux_osl.h b/drivers/net/wireless/bcmdhd/include/linux_osl.h
index 1ec136e..830d351 100644
--- a/drivers/net/wireless/bcmdhd/include/linux_osl.h
+++ b/drivers/net/wireless/bcmdhd/include/linux_osl.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: linux_osl.h,v 13.158.6.3 2010-12-22 23:47:26 Exp $
+ * $Id: linux_osl.h 301794 2011-12-08 20:41:35Z $
*/
@@ -268,7 +268,7 @@
#define PKTLIST_DUMP(osh, buf)
#define PKTDBG_TRACE(osh, pkt, bit)
#define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send))
-#ifdef DHD_USE_STATIC_BUF
+#ifdef CONFIG_DHD_USE_STATIC_BUF
#define PKTGET_STATIC(osh, len, send) osl_pktget_static((osh), (len))
#define PKTFREE_STATIC(osh, skb, send) osl_pktfree_static((osh), (skb), (send))
#endif
diff --git a/drivers/net/wireless/bcmdhd/include/linuxver.h b/drivers/net/wireless/bcmdhd/include/linuxver.h
index 96844db..d269e66 100644
--- a/drivers/net/wireless/bcmdhd/include/linuxver.h
+++ b/drivers/net/wireless/bcmdhd/include/linuxver.h
@@ -22,7 +22,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: linuxver.h,v 13.53.2.2 2010-12-22 23:47:26 Exp $
+ * $Id: linuxver.h 280266 2011-08-28 04:18:20Z $
*/
@@ -482,7 +482,11 @@
#define DBG_THR(x)
#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
+#define SMP_RD_BARRIER_DEPENDS(x) smp_read_barrier_depends(x)
+#else
#define SMP_RD_BARRIER_DEPENDS(x) smp_rmb(x)
+#endif
#define PROC_START(thread_func, owner, tsk_ctl, flags) \
@@ -507,6 +511,18 @@
(tsk_ctl)->thr_pid = -1; \
}
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
+#define DAEMONIZE(a) daemonize(a); \
+ allow_signal(SIGKILL); \
+ allow_signal(SIGTERM);
+#else /* Linux 2.4 (w/o preemption patch) */
+#define RAISE_RX_SOFTIRQ() \
+ cpu_raise_softirq(smp_processor_id(), NET_RX_SOFTIRQ)
+#define DAEMONIZE(a) daemonize(); \
+ do { if (a) \
+ strncpy(current->comm, a, MIN(sizeof(current->comm), (strlen(a) + 1))); \
+ } while (0);
+#endif /* LINUX_VERSION_CODE */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31))
diff --git a/drivers/net/wireless/bcmdhd/include/miniopt.h b/drivers/net/wireless/bcmdhd/include/miniopt.h
index f468420..77eace6 100644
--- a/drivers/net/wireless/bcmdhd/include/miniopt.h
+++ b/drivers/net/wireless/bcmdhd/include/miniopt.h
@@ -20,7 +20,7 @@
* Notwithstanding the above, under no circumstances may you combine this
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
- * $Id: miniopt.h,v 1.3 2009-01-15 00:06:54 Exp $
+ * $Id: miniopt.h 277737 2011-08-16 17:54:59Z $
*/
diff --git a/drivers/net/wireless/bcmdhd/include/msgtrace.h b/drivers/net/wireless/bcmdhd/include/msgtrace.h
index 721d421..088f1e8 100644
--- a/drivers/net/wireless/bcmdhd/include/msgtrace.h
+++ b/drivers/net/wireless/bcmdhd/include/msgtrace.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: msgtrace.h,v 1.4 2009-04-10 04:15:32 Exp $
+ * $Id: msgtrace.h 277737 2011-08-16 17:54:59Z $
*/
#ifndef _MSGTRACE_H
diff --git a/drivers/net/wireless/bcmdhd/include/osl.h b/drivers/net/wireless/bcmdhd/include/osl.h
index 80248ee..b8cc256 100644
--- a/drivers/net/wireless/bcmdhd/include/osl.h
+++ b/drivers/net/wireless/bcmdhd/include/osl.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: osl.h,v 13.44.96.1 2010-05-20 11:09:18 Exp $
+ * $Id: osl.h 277737 2011-08-16 17:54:59Z $
*/
diff --git a/drivers/net/wireless/bcmdhd/include/packed_section_end.h b/drivers/net/wireless/bcmdhd/include/packed_section_end.h
index 5d4a876..71f8b2e 100644
--- a/drivers/net/wireless/bcmdhd/include/packed_section_end.h
+++ b/drivers/net/wireless/bcmdhd/include/packed_section_end.h
@@ -34,7 +34,7 @@
* Notwithstanding the above, under no circumstances may you combine this
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
- * $Id: packed_section_end.h,v 1.4 2008-12-09 23:43:22 Exp $
+ * $Id: packed_section_end.h 277737 2011-08-16 17:54:59Z $
*/
diff --git a/drivers/net/wireless/bcmdhd/include/packed_section_start.h b/drivers/net/wireless/bcmdhd/include/packed_section_start.h
index da2fed6..afc2ba3 100644
--- a/drivers/net/wireless/bcmdhd/include/packed_section_start.h
+++ b/drivers/net/wireless/bcmdhd/include/packed_section_start.h
@@ -34,7 +34,7 @@
* Notwithstanding the above, under no circumstances may you combine this
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
- * $Id: packed_section_start.h,v 1.4.124.1 2010-09-17 00:47:03 Exp $
+ * $Id: packed_section_start.h 277737 2011-08-16 17:54:59Z $
*/
diff --git a/drivers/net/wireless/bcmdhd/include/pcicfg.h b/drivers/net/wireless/bcmdhd/include/pcicfg.h
index fae063a..6619943 100644
--- a/drivers/net/wireless/bcmdhd/include/pcicfg.h
+++ b/drivers/net/wireless/bcmdhd/include/pcicfg.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: pcicfg.h,v 1.50 2009-12-07 21:56:06 Exp $
+ * $Id: pcicfg.h 277737 2011-08-16 17:54:59Z $
*/
@@ -39,6 +39,19 @@
#define PCI_INT_MASK 0x94
#define PCIE_EXTCFG_OFFSET 0x100
+#define PCI_SPROM_CONTROL 0x88
+#define PCI_BAR1_CONTROL 0x8c
+#define PCI_TO_SB_MB 0x98
+#define PCI_BACKPLANE_ADDR 0xa0
+#define PCI_BACKPLANE_DATA 0xa4
+#define PCI_CLK_CTL_ST 0xa8
+#define PCI_BAR0_WIN2 0xac
+#define PCI_GPIO_IN 0xb0
+#define PCI_GPIO_OUT 0xb4
+#define PCI_GPIO_OUTEN 0xb8
+
+#define PCI_BAR0_SHADOW_OFFSET (2 * 1024)
+#define PCI_BAR0_SPROM_OFFSET (4 * 1024)
#define PCI_BAR0_PCIREGS_OFFSET (6 * 1024)
#define PCI_BAR0_PCISBR_OFFSET (4 * 1024)
@@ -49,4 +62,17 @@
#define PCI_16KB0_CCREGS_OFFSET (12 * 1024)
#define PCI_16KBB0_WINSZ (16 * 1024)
+
+#define PCI_16KB0_WIN2_OFFSET (4 * 1024)
+
+
+
+#define SPROM_SZ_MSK 0x02
+#define SPROM_LOCKED 0x08
+#define SPROM_BLANK 0x04
+#define SPROM_WRITEEN 0x10
+#define SPROM_BOOTROM_WE 0x20
+#define SPROM_BACKPLANE_EN 0x40
+#define SPROM_OTPIN_USE 0x80
+
#endif
diff --git a/drivers/net/wireless/bcmdhd/include/proto/802.11.h b/drivers/net/wireless/bcmdhd/include/proto/802.11.h
index 2342cb3..fd69aac 100644
--- a/drivers/net/wireless/bcmdhd/include/proto/802.11.h
+++ b/drivers/net/wireless/bcmdhd/include/proto/802.11.h
@@ -21,7 +21,7 @@
*
* Fundamental types and constants relating to 802.11
*
- * $Id: 802.11.h,v 9.260.2.6 2010-12-15 21:41:14 Exp $
+ * $Id: 802.11.h 304058 2011-12-21 00:39:12Z $
*/
@@ -429,10 +429,26 @@
BWL_PRE_PACKED_STRUCT struct dot11_extcap_ie {
uint8 id;
uint8 len;
- uint8 cap;
+ uint8 cap[1];
} BWL_POST_PACKED_STRUCT;
typedef struct dot11_extcap_ie dot11_extcap_ie_t;
#define DOT11_EXTCAP_LEN 1
+#define DOT11_EXTCAP_LEN_TDLS 5
+
+BWL_PRE_PACKED_STRUCT struct dot11_extcap {
+ uint8 extcap[DOT11_EXTCAP_LEN_TDLS];
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_extcap dot11_extcap_t;
+
+
+#define TDLS_CAP_TDLS 37
+#define TDLS_CAP_PU_BUFFER_STA 28
+#define TDLS_CAP_PEER_PSM 20
+#define TDLS_CAP_CH_SW 30
+#define TDLS_CAP_PROH 38
+#define TDLS_CAP_CH_SW_PROH 39
+
+#define TDLS_CAP_MAX_BIT 39
@@ -545,6 +561,9 @@
#define WME_SUBTYPE_IE 0
#define WME_SUBTYPE_PARAM_IE 1
#define WME_SUBTYPE_TSPEC 2
+#define WME_VERSION_LEN 1
+#define WME_PARAMETER_IE_LEN 24
+
#define AC_BE 0
@@ -709,6 +728,15 @@
#define DOT11_MGMT_NOTIFICATION_LEN 4
+BWL_PRE_PACKED_STRUCT struct ti_ie {
+ uint8 ti_type;
+ uint32 ti_val;
+} BWL_POST_PACKED_STRUCT;
+typedef struct ti_ie ti_ie_t;
+#define TI_TYPE_REASSOC_DEADLINE 1
+#define TI_TYPE_KEY_LIFETIME 2
+
+
#define WME_ADDTS_REQUEST 0
#define WME_ADDTS_RESPONSE 1
#define WME_DELTS_REQUEST 2
@@ -724,8 +752,7 @@
#define DOT11_OPEN_SYSTEM 0
#define DOT11_SHARED_KEY 1
-#define DOT11_OPEN_SHARED 2
-#define DOT11_FAST_BSS 3
+#define DOT11_FAST_BSS 2
#define DOT11_CHALLENGE_LEN 128
@@ -926,9 +953,18 @@
#define DOT11_RC_MAX 23
+#define DOT11_RC_TDLS_PEER_UNREACH 25
+#define DOT11_RC_TDLS_DOWN_UNSPECIFIED 26
+
#define DOT11_SC_SUCCESS 0
#define DOT11_SC_FAILURE 1
+#define DOT11_SC_TDLS_WAKEUP_SCH_ALT 2
+
+#define DOT11_SC_TDLS_WAKEUP_SCH_REJ 3
+#define DOT11_SC_TDLS_SEC_DISABLED 5
+#define DOT11_SC_LIFETIME_REJ 6
+#define DOT11_SC_NOT_SAME_BSS 7
#define DOT11_SC_CAP_MISMATCH 10
#define DOT11_SC_REASSOC_FAIL 11
#define DOT11_SC_ASSOC_FAIL 12
@@ -947,13 +983,22 @@
#define DOT11_SC_ASSOC_SHORTSLOT_REQUIRED 25
#define DOT11_SC_ASSOC_ERPBCC_REQUIRED 26
#define DOT11_SC_ASSOC_DSSOFDM_REQUIRED 27
+#define DOT11_SC_ASSOC_R0KH_UNREACHABLE 28
+#define DOT11_SC_ASSOC_TRY_LATER 30
+#define DOT11_SC_ASSOC_MFP_VIOLATION 31
-#define DOT11_SC_DECLINED 37
-#define DOT11_SC_INVALID_PARAMS 38
-#define DOT11_SC_INVALID_AKMP 43
-#define DOT11_SC_INVALID_MDID 54
-#define DOT11_SC_INVALID_FTIE 55
+#define DOT11_SC_DECLINED 37
+#define DOT11_SC_INVALID_PARAMS 38
+#define DOT11_SC_INVALID_PAIRWISE_CIPHER 42
+#define DOT11_SC_INVALID_AKMP 43
+#define DOT11_SC_INVALID_RSNIE_CAP 45
+#define DOT11_SC_INVALID_PMKID 53
+#define DOT11_SC_INVALID_MDID 54
+#define DOT11_SC_INVALID_FTIE 55
+#define DOT11_SC_UNEXP_MSG 70
+#define DOT11_SC_INVALID_SNONCE 71
+#define DOT11_SC_INVALID_RSNIE 72
#define DOT11_MNG_DS_PARAM_LEN 1
#define DOT11_MNG_IBSS_PARAM_LEN 2
@@ -1008,6 +1053,7 @@
#define DOT11_MNG_MDIE_ID 54
#define DOT11_MNG_FTIE_ID 55
#define DOT11_MNG_FT_TI_ID 56
+#define DOT11_MNG_RDE_ID 57
#define DOT11_MNG_REGCLASS_ID 59
#define DOT11_MNG_EXT_CSA_ID 60
#define DOT11_MNG_HT_ADD 61
@@ -1018,7 +1064,13 @@
#define DOT11_MNG_HT_BSS_COEXINFO_ID 72
#define DOT11_MNG_HT_BSS_CHANNEL_REPORT_ID 73
#define DOT11_MNG_HT_OBSS_ID 74
-#define DOT11_MNG_EXT_CAP 127
+#define DOT11_MNG_CHANNEL_USAGE 97
+#define DOT11_MNG_LINK_IDENTIFIER_ID 101
+#define DOT11_MNG_WAKEUP_SCHEDULE_ID 102
+#define DOT11_MNG_CHANNEL_SWITCH_TIMING_ID 104
+#define DOT11_MNG_PTI_CONTROL_ID 105
+#define DOT11_MNG_PU_BUFFER_STATUS_ID 106
+#define DOT11_MNG_EXT_CAP_ID 127
#define DOT11_MNG_WPA_ID 221
#define DOT11_MNG_PROPR_ID 221
@@ -1070,8 +1122,14 @@
#define DOT11_ACTION_CAT_RRM 5
#define DOT11_ACTION_CAT_FBT 6
#define DOT11_ACTION_CAT_HT 7
+#if defined(MFP) || defined(WLFBT) || defined(WLWNM)
+#define DOT11_ACTION_CAT_SA_QUERY 8
+#define DOT11_ACTION_CAT_PDPA 9
#define DOT11_ACTION_CAT_BSSMGMT 10
#define DOT11_ACTION_NOTIFICATION 17
+#define DOT11_ACTION_CAT_VSP 126
+#endif
+#define DOT11_ACTION_NOTIFICATION 17
#define DOT11_ACTION_CAT_VS 127
@@ -1107,6 +1165,121 @@
#define DOT11_ADDBA_POLICY_DELAYED 0
#define DOT11_ADDBA_POLICY_IMMEDIATE 1
+
+#define DOT11_FT_ACTION_FT_RESERVED 0
+#define DOT11_FT_ACTION_FT_REQ 1
+#define DOT11_FT_ACTION_FT_RES 2
+#define DOT11_FT_ACTION_FT_CON 3
+#define DOT11_FT_ACTION_FT_ACK 4
+
+
+
+#define DOT11_WNM_ACTION_EVENT_REQ 0
+#define DOT11_WNM_ACTION_EVENT_REP 1
+#define DOT11_WNM_ACTION_DIAG_REQ 2
+#define DOT11_WNM_ACTION_DIAG_REP 3
+#define DOT11_WNM_ACTION_LOC_CFG_REQ 4
+#define DOT11_WNM_ACTION_LOC_RFG_RESP 5
+#define DOT11_WNM_ACTION_BSS_TRANS_QURY 6
+#define DOT11_WNM_ACTION_BSS_TRANS_REQ 7
+#define DOT11_WNM_ACTION_BSS_TRANS_RESP 8
+#define DOT11_WNM_ACTION_FMS_REQ 9
+#define DOT11_WNM_ACTION_FMS_RESP 10
+#define DOT11_WNM_ACTION_COL_INTRFRNCE_REQ 11
+#define DOT11_WNM_ACTION_COL_INTRFRNCE_REP 12
+#define DOT11_WNM_ACTION_TFS_REQ 13
+#define DOT11_WNM_ACTION_TFS_RESP 14
+#define DOT11_WNM_ACTION_TFS_NOTIFY 15
+#define DOT11_WNM_ACTION_WNM_SLEEP_REQ 16
+#define DOT11_WNM_ACTION_WNM_SLEEP_RESP 17
+#define DOT11_WNM_ACTION_TIM_BCAST_REQ 18
+#define DOT11_WNM_ACTION_TIM_BCAST_RESP 19
+#define DOT11_WNM_ACTION_QOS_TRFC_CAP_UPD 20
+#define DOT11_WNM_ACTION_CHAN_USAGE_REQ 21
+#define DOT11_WNM_ACTION_CHAN_USAGE_RESP 22
+#define DOT11_WNM_ACTION_DMS_REQ 23
+#define DOT11_WNM_ACTION_DMS_RESP 24
+#define DOT11_WNM_ACTION_TMNG_MEASUR_REQ 25
+#define DOT11_WNM_ACTION_NOTFCTN_REQ 26
+#define DOT11_WNM_ACTION_NOTFCTN_RES 27
+
+
+
+BWL_PRE_PACKED_STRUCT struct dot11_bss_trans_query {
+ uint8 category;
+ uint8 action;
+ uint8 token;
+ uint8 reason;
+ uint8 data[1];
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_bss_trans_query dot11_bss_trans_query_t;
+#define DOT11_BSS_TRANS_QUERY_LEN 4
+
+
+BWL_PRE_PACKED_STRUCT struct dot11_bss_trans_req {
+ uint8 category;
+ uint8 action;
+ uint8 token;
+ uint8 reqmode;
+ uint16 disassoc_tmr;
+ uint8 validity_intrvl;
+ uint8 data[1];
+
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_bss_trans_req dot11_bss_trans_req_t;
+#define DOT11_BSS_TRANS_REQ_LEN 7
+
+#define DOT11_BSS_TERM_DUR_LEN 12
+
+
+
+#define DOT11_BSS_TRNS_REQMODE_PREF_LIST_INCL 0x01
+#define DOT11_BSS_TRNS_REQMODE_ABRIDGED 0x02
+#define DOT11_BSS_TRNS_REQMODE_DISASSOC_IMMINENT 0x04
+#define DOT11_BSS_TRNS_REQMODE_BSS_TERM_INCL 0x08
+#define DOT11_BSS_TRNS_REQMODE_ESS_DISASSOC_IMNT 0x10
+
+
+
+BWL_PRE_PACKED_STRUCT struct dot11_bss_trans_res {
+ uint8 category;
+ uint8 action;
+ uint8 token;
+ uint8 status;
+ uint8 term_delay;
+ uint8 data[1];
+
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_bss_trans_res dot11_bss_trans_res_t;
+#define DOT11_BSS_TRANS_RES_LEN 5
+
+
+#define DOT11_BSS_TRNS_RES_STATUS_ACCEPT 0
+#define DOT11_BSS_TRNS_RES_STATUS_REJECT 1
+#define DOT11_BSS_TRNS_RES_STATUS_REJ_INSUFF_BCN 2
+#define DOT11_BSS_TRNS_RES_STATUS_REJ_INSUFF_CAP 3
+#define DOT11_BSS_TRNS_RES_STATUS_REJ_TERM_UNDESIRED 4
+#define DOT11_BSS_TRNS_RES_STATUS_REJ_TERM_DELAY_REQ 5
+#define DOT11_BSS_TRNS_RES_STATUS_REJ_BSS_LIST_PROVIDED 6
+#define DOT11_BSS_TRNS_RES_STATUS_REJ_NO_SUITABLE_BSS 7
+#define DOT11_BSS_TRNS_RES_STATUS_REJ_LEAVING_ESS 8
+
+
+
+#define DOT11_NBR_RPRT_BSSID_INFO_REACHABILTY 0x0003
+#define DOT11_NBR_RPRT_BSSID_INFO_SEC 0x0004
+#define DOT11_NBR_RPRT_BSSID_INFO_KEY_SCOPE 0x0008
+#define DOT11_NBR_RPRT_BSSID_INFO_CAP 0x03f0
+
+#define DOT11_NBR_RPRT_BSSID_INFO_CAP_SPEC_MGMT 0x0010
+#define DOT11_NBR_RPRT_BSSID_INFO_CAP_QOS 0x0020
+#define DOT11_NBR_RPRT_BSSID_INFO_CAP_APSD 0x0040
+#define DOT11_NBR_RPRT_BSSID_INFO_CAP_RDIO_MSMT 0x0080
+#define DOT11_NBR_RPRT_BSSID_INFO_CAP_DEL_BA 0x0100
+#define DOT11_NBR_RPRT_BSSID_INFO_CAP_IMM_BA 0x0200
+
+
+#define DOT11_NBR_RPRT_SUBELEM_BSS_CANDDT_PREF_ID 3
BWL_PRE_PACKED_STRUCT struct dot11_addba_req {
uint8 category;
uint8 action;
@@ -1145,6 +1318,48 @@
#define DOT11_DELBA_LEN 6
+#define SA_QUERY_REQUEST 0
+#define SA_QUERY_RESPONSE 1
+
+
+
+
+BWL_PRE_PACKED_STRUCT struct dot11_ft_req {
+ uint8 category;
+ uint8 action;
+ uint8 sta_addr[ETHER_ADDR_LEN];
+ uint8 tgt_ap_addr[ETHER_ADDR_LEN];
+ uint8 data[1];
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_ft_req dot11_ft_req_t;
+#define DOT11_FT_REQ_FIXED_LEN 14
+
+
+BWL_PRE_PACKED_STRUCT struct dot11_ft_res {
+ uint8 category;
+ uint8 action;
+ uint8 sta_addr[ETHER_ADDR_LEN];
+ uint8 tgt_ap_addr[ETHER_ADDR_LEN];
+ uint16 status;
+ uint8 data[1];
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_ft_res dot11_ft_res_t;
+#define DOT11_FT_RES_FIXED_LEN 16
+
+
+BWL_PRE_PACKED_STRUCT struct dot11_rde_ie {
+ uint8 id;
+ uint8 length;
+ uint8 rde_id;
+ uint8 rd_count;
+ uint16 status;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_rde_ie dot11_rde_ie_t;
+
+
+#define DOT11_MNG_RDE_IE_LEN sizeof(dot11_rde_ie_t)
+
+
@@ -1166,6 +1381,28 @@
#define DOT11_RRM_CAP_AP_CHANREP 16
+
+#define DOT11_EXT_CAP_LEN 4
+BWL_PRE_PACKED_STRUCT struct dot11_ext_cap_ie {
+ uint8 cap[DOT11_EXT_CAP_LEN];
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_ext_cap_ie dot11_ext_cap_ie_t;
+
+
+#define DOT11_EXT_CAP_BSS_TRANSITION_MGMT 19
+
+
+#define DOT11_OP_CLASS_NONE 255
+
+BWL_PRE_PACKED_STRUCT struct do11_ap_chrep {
+ uint8 id;
+ uint8 len;
+ uint8 reg;
+ uint8 chanlist[1];
+} BWL_POST_PACKED_STRUCT;
+typedef struct do11_ap_chrep dot11_ap_chrep_t;
+
+
#define DOT11_RM_ACTION_RM_REQ 0
#define DOT11_RM_ACTION_RM_REP 1
#define DOT11_RM_ACTION_LM_REQ 2
@@ -1255,7 +1492,7 @@
#define DOT11_RMREQ_BCN_REPINFO_ID 1
#define DOT11_RMREQ_BCN_REPDET_ID 2
#define DOT11_RMREQ_BCN_REQUEST_ID 10
-#define DOT11_RMREQ_BCN_APCHREP_ID 51
+#define DOT11_RMREQ_BCN_APCHREP_ID DOT11_MNG_AP_CHREP_ID
#define DOT11_RMREQ_BCN_REPDET_FIXED 0
@@ -1272,6 +1509,7 @@
uint8 reg;
uint8 channel;
uint8 phytype;
+ uchar sub_elements[1];
} BWL_POST_PACKED_STRUCT;
typedef struct dot11_rmrep_nbr dot11_rmrep_nbr_t;
#define DOT11_RMREP_NBR_LEN 13
@@ -1660,6 +1898,9 @@
#define RSN_AKM_PSK 2
#define RSN_AKM_FBT_1X 3
#define RSN_AKM_FBT_PSK 4
+#define RSN_AKM_MFP_1X 5
+#define RSN_AKM_MFP_PSK 6
+#define RSN_AKM_TPK 7
#define DOT11_MAX_DEFAULT_KEYS 4
@@ -1724,6 +1965,66 @@
} BWL_POST_PACKED_STRUCT;
typedef struct dot11_gtk_ie dot11_gtk_ie_t;
+#define BSSID_INVALID "\x00\x00\x00\x00\x00\x00"
+#define BSSID_BROADCAST "\xFF\xFF\xFF\xFF\xFF\xFF"
+
+
+
+BWL_PRE_PACKED_STRUCT struct link_id_ie {
+ uint8 id;
+ uint8 len;
+ struct ether_addr bssid;
+ struct ether_addr tdls_init_mac;
+ struct ether_addr tdls_resp_mac;
+} BWL_POST_PACKED_STRUCT;
+typedef struct link_id_ie link_id_ie_t;
+#define TDLS_LINK_ID_IE_LEN 18
+
+
+BWL_PRE_PACKED_STRUCT struct wakeup_sch_ie {
+ uint8 id;
+ uint8 len;
+ uint32 offset;
+ uint32 interval;
+ uint32 awake_win_slots;
+ uint32 max_wake_win;
+ uint16 idle_cnt;
+} BWL_POST_PACKED_STRUCT;
+typedef struct wakeup_sch_ie wakeup_sch_ie_t;
+#define TDLS_WAKEUP_SCH_IE_LEN 18
+
+
+BWL_PRE_PACKED_STRUCT struct channel_switch_timing_ie {
+ uint8 id;
+ uint8 len;
+ uint16 switch_time;
+ uint16 switch_timeout;
+} BWL_POST_PACKED_STRUCT;
+typedef struct channel_switch_timing_ie channel_switch_timing_ie_t;
+#define TDLS_CHANNEL_SWITCH_TIMING_IE_LEN 4
+
+
+BWL_PRE_PACKED_STRUCT struct pti_control_ie {
+ uint8 id;
+ uint8 len;
+ uint8 tid;
+ uint16 seq_control;
+} BWL_POST_PACKED_STRUCT;
+typedef struct pti_control_ie pti_control_ie_t;
+#define TDLS_PTI_CONTROL_IE_LEN 3
+
+
+BWL_PRE_PACKED_STRUCT struct pu_buffer_status_ie {
+ uint8 id;
+ uint8 len;
+ uint8 status;
+} BWL_POST_PACKED_STRUCT;
+typedef struct pu_buffer_status_ie pu_buffer_status_ie_t;
+#define TDLS_PU_BUFFER_STATUS_IE_LEN 1
+#define TDLS_PU_BUFFER_STATUS_AC_BK 1
+#define TDLS_PU_BUFFER_STATUS_AC_BE 2
+#define TDLS_PU_BUFFER_STATUS_AC_VI 4
+#define TDLS_PU_BUFFER_STATUS_AC_VO 8
#include <packed_section_end.h>
diff --git a/drivers/net/wireless/bcmdhd/include/proto/802.11_bta.h b/drivers/net/wireless/bcmdhd/include/proto/802.11_bta.h
index 4ccfab0..cbdd05e 100644
--- a/drivers/net/wireless/bcmdhd/include/proto/802.11_bta.h
+++ b/drivers/net/wireless/bcmdhd/include/proto/802.11_bta.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: 802.11_bta.h,v 9.2 2008-10-28 23:27:13 Exp $
+ * $Id: 802.11_bta.h 277737 2011-08-16 17:54:59Z $
*/
#ifndef _802_11_BTA_H_
diff --git a/drivers/net/wireless/bcmdhd/include/proto/802.11e.h b/drivers/net/wireless/bcmdhd/include/proto/802.11e.h
index ce8ad08..0e070a4 100644
--- a/drivers/net/wireless/bcmdhd/include/proto/802.11e.h
+++ b/drivers/net/wireless/bcmdhd/include/proto/802.11e.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: 802.11e.h,v 1.6 2008-12-01 22:55:11 Exp $
+ * $Id: 802.11e.h 277737 2011-08-16 17:54:59Z $
*/
#ifndef _802_11e_H_
diff --git a/drivers/net/wireless/bcmdhd/include/proto/802.1d.h b/drivers/net/wireless/bcmdhd/include/proto/802.1d.h
index cf20625..c7e07bd 100644
--- a/drivers/net/wireless/bcmdhd/include/proto/802.1d.h
+++ b/drivers/net/wireless/bcmdhd/include/proto/802.1d.h
@@ -21,7 +21,7 @@
*
* Fundamental types and constants relating to 802.1D
*
- * $Id: 802.1d.h,v 9.3 2007-04-10 21:33:06 Exp $
+ * $Id: 802.1d.h 277737 2011-08-16 17:54:59Z $
*/
diff --git a/drivers/net/wireless/bcmdhd/include/proto/bcmeth.h b/drivers/net/wireless/bcmdhd/include/proto/bcmeth.h
index 46fa4c9..0f75d3c 100644
--- a/drivers/net/wireless/bcmdhd/include/proto/bcmeth.h
+++ b/drivers/net/wireless/bcmdhd/include/proto/bcmeth.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: bcmeth.h,v 9.12 2009-12-29 19:57:18 Exp $
+ * $Id: bcmeth.h 277737 2011-08-16 17:54:59Z $
*/
diff --git a/drivers/net/wireless/bcmdhd/include/proto/bcmevent.h b/drivers/net/wireless/bcmdhd/include/proto/bcmevent.h
index 30ec848..e8c2387 100644
--- a/drivers/net/wireless/bcmdhd/include/proto/bcmevent.h
+++ b/drivers/net/wireless/bcmdhd/include/proto/bcmevent.h
@@ -23,7 +23,7 @@
*
* Dependencies: proto/bcmeth.h
*
- * $Id: bcmevent.h,v 9.64.2.9 2011-02-01 06:24:21 Exp $
+ * $Id: bcmevent.h 288077 2011-10-06 00:08:47Z $
*
*/
@@ -182,7 +182,10 @@
#define WLC_E_PFN_SCAN_NONE 82
#define WLC_E_PFN_SCAN_ALLGONE 83
#define WLC_E_GTK_PLUMBED 84
-#define WLC_E_LAST 85
+#define WLC_E_ASSOC_REQ_IE 85
+#define WLC_E_ASSOC_RESP_IE 86
+#define WLC_E_LAST 87
+
typedef struct {
@@ -226,6 +229,8 @@
#define WLC_E_REASON_TSPEC_REJECTED 7
#define WLC_E_REASON_BETTER_AP 8
+#define WLC_E_REASON_REQUESTED_ROAM 11
+
#define WLC_E_PRUNE_ENCR_MISMATCH 1
#define WLC_E_PRUNE_BCAST_BSSID 2
diff --git a/drivers/net/wireless/bcmdhd/include/proto/bcmip.h b/drivers/net/wireless/bcmdhd/include/proto/bcmip.h
index 8a8f314..55eff24 100644
--- a/drivers/net/wireless/bcmdhd/include/proto/bcmip.h
+++ b/drivers/net/wireless/bcmdhd/include/proto/bcmip.h
@@ -21,7 +21,7 @@
*
* Fundamental constants relating to IP Protocol
*
- * $Id: bcmip.h,v 9.19 2009-11-10 20:08:33 Exp $
+ * $Id: bcmip.h 277737 2011-08-16 17:54:59Z $
*/
diff --git a/drivers/net/wireless/bcmdhd/include/proto/bt_amp_hci.h b/drivers/net/wireless/bcmdhd/include/proto/bt_amp_hci.h
index 89c1181..91ab4fe 100644
--- a/drivers/net/wireless/bcmdhd/include/proto/bt_amp_hci.h
+++ b/drivers/net/wireless/bcmdhd/include/proto/bt_amp_hci.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: bt_amp_hci.h,v 9.14.8.2 2010-09-10 18:37:47 Exp $
+ * $Id: bt_amp_hci.h 277737 2011-08-16 17:54:59Z $
*/
#ifndef _bt_amp_hci_h
diff --git a/drivers/net/wireless/bcmdhd/include/proto/eapol.h b/drivers/net/wireless/bcmdhd/include/proto/eapol.h
index 5781d13..92634c1 100644
--- a/drivers/net/wireless/bcmdhd/include/proto/eapol.h
+++ b/drivers/net/wireless/bcmdhd/include/proto/eapol.h
@@ -7,7 +7,7 @@
*
* Copyright (C) 2002 Broadcom Corporation
*
- * $Id: eapol.h,v 9.23.86.1 2010-09-02 18:09:39 Exp $
+ * $Id: eapol.h 277737 2011-08-16 17:54:59Z $
*/
#ifndef _eapol_h_
diff --git a/drivers/net/wireless/bcmdhd/include/proto/ethernet.h b/drivers/net/wireless/bcmdhd/include/proto/ethernet.h
index 6a6dd14..20865dc 100644
--- a/drivers/net/wireless/bcmdhd/include/proto/ethernet.h
+++ b/drivers/net/wireless/bcmdhd/include/proto/ethernet.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: ethernet.h,v 9.56 2009-10-15 22:54:58 Exp $
+ * $Id: ethernet.h 285437 2011-09-21 22:16:56Z $
*/
@@ -69,6 +69,7 @@
#define ETHER_TYPE_802_1X 0x888e
#define ETHER_TYPE_802_1X_PREAUTH 0x88c7
#define ETHER_TYPE_WAI 0x88b4
+#define ETHER_TYPE_89_0D 0x890d
diff --git a/drivers/net/wireless/bcmdhd/include/proto/p2p.h b/drivers/net/wireless/bcmdhd/include/proto/p2p.h
index 4a0c9d1..d2bf3f2 100644
--- a/drivers/net/wireless/bcmdhd/include/proto/p2p.h
+++ b/drivers/net/wireless/bcmdhd/include/proto/p2p.h
@@ -21,7 +21,7 @@
*
* Fundamental types and constants relating to WFA P2P (aka WiFi Direct)
*
- * $Id: p2p.h,v 9.17.2.4 2010-12-15 21:41:21 Exp $
+ * $Id: p2p.h 277737 2011-08-16 17:54:59Z $
*/
#ifndef _P2P_H_
diff --git a/drivers/net/wireless/bcmdhd/include/proto/sdspi.h b/drivers/net/wireless/bcmdhd/include/proto/sdspi.h
index 7fe4fbc..7353ff0 100644
--- a/drivers/net/wireless/bcmdhd/include/proto/sdspi.h
+++ b/drivers/net/wireless/bcmdhd/include/proto/sdspi.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: sdspi.h,v 9.2.120.1 2010-11-15 17:56:25 Exp $
+ * $Id: sdspi.h 277737 2011-08-16 17:54:59Z $
*/
#ifndef _SD_SPI_H
diff --git a/drivers/net/wireless/bcmdhd/include/proto/vlan.h b/drivers/net/wireless/bcmdhd/include/proto/vlan.h
index 07fa7e4..27f0055 100644
--- a/drivers/net/wireless/bcmdhd/include/proto/vlan.h
+++ b/drivers/net/wireless/bcmdhd/include/proto/vlan.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: vlan.h,v 9.7 2009-03-13 01:11:50 Exp $
+ * $Id: vlan.h 277737 2011-08-16 17:54:59Z $
*/
diff --git a/drivers/net/wireless/bcmdhd/include/proto/wpa.h b/drivers/net/wireless/bcmdhd/include/proto/wpa.h
index 1ff06dc..7361cbf 100644
--- a/drivers/net/wireless/bcmdhd/include/proto/wpa.h
+++ b/drivers/net/wireless/bcmdhd/include/proto/wpa.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: wpa.h,v 1.19 2009-07-13 08:29:58 Exp $
+ * $Id: wpa.h 285437 2011-09-21 22:16:56Z $
*/
@@ -114,6 +114,8 @@
#define WPA_CIPHER_AES_OCB 3
#define WPA_CIPHER_AES_CCM 4
#define WPA_CIPHER_WEP_104 5
+#define WPA_CIPHER_BIP 6
+#define WPA_CIPHER_TPK 7
#define IS_WPA_CIPHER(cipher) ((cipher) == WPA_CIPHER_NONE || \
@@ -121,7 +123,9 @@
(cipher) == WPA_CIPHER_WEP_104 || \
(cipher) == WPA_CIPHER_TKIP || \
(cipher) == WPA_CIPHER_AES_OCB || \
- (cipher) == WPA_CIPHER_AES_CCM)
+ (cipher) == WPA_CIPHER_AES_CCM || \
+ (cipher) == WPA_CIPHER_TPK)
+
#define WPA_TKIP_CM_DETECT 60
@@ -149,7 +153,11 @@
#define WPA_CAP_REPLAY_CNTR_MASK RSN_CAP_PTK_REPLAY_CNTR_MASK
+#define WPA_CAP_PEER_KEY_ENABLE (0x1 << 1)
+
+
#define WPA_CAP_LEN RSN_CAP_LEN
+#define WPA_PMKID_CNT_LEN 2
#define WPA_CAP_WPA2_PREAUTH RSN_CAP_PREAUTH
diff --git a/drivers/net/wireless/bcmdhd/include/sbchipc.h b/drivers/net/wireless/bcmdhd/include/sbchipc.h
index cbd3749..3fe2a5a 100644
--- a/drivers/net/wireless/bcmdhd/include/sbchipc.h
+++ b/drivers/net/wireless/bcmdhd/include/sbchipc.h
@@ -5,7 +5,7 @@
* JTAG, 0/1/2 UARTs, clock frequency control, a watchdog interrupt timer,
* GPIO interface, extbus, and support for serial and parallel flashes.
*
- * $Id: sbchipc.h,v 13.169.2.14 2011-02-10 23:43:55 Exp $
+ * $Id: sbchipc.h 277737 2011-08-16 17:54:59Z $
*
* Copyright (C) 1999-2011, Broadcom Corporation
*
@@ -41,6 +41,50 @@
#define PAD _XSTR(__LINE__)
#endif
+typedef struct eci_prerev35 {
+ uint32 eci_output;
+ uint32 eci_control;
+ uint32 eci_inputlo;
+ uint32 eci_inputmi;
+ uint32 eci_inputhi;
+ uint32 eci_inputintpolaritylo;
+ uint32 eci_inputintpolaritymi;
+ uint32 eci_inputintpolarityhi;
+ uint32 eci_intmasklo;
+ uint32 eci_intmaskmi;
+ uint32 eci_intmaskhi;
+ uint32 eci_eventlo;
+ uint32 eci_eventmi;
+ uint32 eci_eventhi;
+ uint32 eci_eventmasklo;
+ uint32 eci_eventmaskmi;
+ uint32 eci_eventmaskhi;
+ uint32 PAD[3];
+} eci_prerev35_t;
+
+typedef struct eci_rev35 {
+ uint32 eci_outputlo;
+ uint32 eci_outputhi;
+ uint32 eci_controllo;
+ uint32 eci_controlhi;
+ uint32 eci_inputlo;
+ uint32 eci_inputhi;
+ uint32 eci_inputintpolaritylo;
+ uint32 eci_inputintpolarityhi;
+ uint32 eci_intmasklo;
+ uint32 eci_intmaskhi;
+ uint32 eci_eventlo;
+ uint32 eci_eventhi;
+ uint32 eci_eventmasklo;
+ uint32 eci_eventmaskhi;
+ uint32 eci_auxtx;
+ uint32 eci_auxrx;
+ uint32 eci_datatag;
+ uint32 eci_uartescvalue;
+ uint32 eci_autobaudctr;
+ uint32 eci_uartfifolevel;
+} eci_rev35_t;
+
typedef volatile struct {
uint32 chipid;
uint32 capabilities;
@@ -153,10 +197,26 @@
uint32 prog_waitcount;
uint32 flash_config;
uint32 flash_waitcount;
- uint32 PAD[4];
- uint32 PAD[40];
+ uint32 SECI_config;
+ uint32 SECI_status;
+ uint32 SECI_statusmask;
+ uint32 SECI_rxnibchanged;
+
+ uint32 PAD[20];
+ uint32 sromcontrol;
+ uint32 sromaddress;
+ uint32 sromdata;
+ uint32 PAD[9];
+ uint32 seci_uart_data;
+ uint32 seci_uart_bauddiv;
+ uint32 seci_uart_fcr;
+ uint32 seci_uart_lcr;
+ uint32 seci_uart_mcr;
+ uint32 seci_uart_lsr;
+ uint32 seci_uart_msr;
+ uint32 seci_uart_baudadj;
uint32 clk_ctl_st;
uint32 hw_war;
@@ -1332,9 +1392,27 @@
#define CST43237_BOOT_FROM_INVALID 3
+#define RES43239_CBUCK_LPOM 0
+#define RES43239_CBUCK_BURST 1
+#define RES43239_CBUCK_LP_PWM 2
+#define RES43239_CBUCK_PWM 3
+#define RES43239_CLDO_PU 4
+#define RES43239_DIS_INT_RESET_PD 5
+#define RES43239_ILP_REQUEST 6
+#define RES43239_LNLDO_PU 7
+#define RES43239_LDO3P3_PU 8
#define RES43239_OTP_PU 9
+#define RES43239_XTAL_PU 10
+#define RES43239_ALP_AVAIL 11
+#define RES43239_RADIO_PU 12
#define RES43239_MACPHY_CLKAVAIL 23
#define RES43239_HT_AVAIL 24
+#define RES43239_XOLDO_PU 25
+#define RES43239_WL_XTAL_CTL_SEL 26
+#define RES43239_SR_CLK_STABLE 27
+#define RES43239_SR_SAVE_RESTORE 28
+#define RES43239_SR_PHY_PIC 29
+#define RES43239_SR_PHY_PWR_SW 30
#define CST43239_SPROM_MASK 0x00000002
@@ -1342,7 +1420,7 @@
#define CST43239_RES_INIT_MODE_SHIFT 7
#define CST43239_RES_INIT_MODE_MASK 0x000001f0
#define CST43239_CHIPMODE_SDIOD(cs) ((cs) & (1 << 15))
-#define CST43239_CHIPMODE_USB20D(cs) ((cs) & !(1 << 15))
+#define CST43239_CHIPMODE_USB20D(cs) (~(cs) & (1 << 15))
#define CST43239_CHIPMODE_SDIO(cs) (((cs) & (1 << 0)) == 0)
#define CST43239_CHIPMODE_GSPI(cs) (((cs) & (1 << 0)) == (1 << 0))
@@ -1350,6 +1428,40 @@
#define CCTRL43239_XTAL_STRENGTH(ctl) ((ctl & 0x3F) << 12)
+#define RES4331_REGULATOR 0
+#define RES4331_ILP_REQUEST 1
+#define RES4331_XTAL_PU 2
+#define RES4331_ALP_AVAIL 3
+#define RES4331_SI_PLL_ON 4
+#define RES4331_HT_SI_AVAIL 5
+
+
+#define CCTRL4331_BT_COEXIST (1<<0)
+#define CCTRL4331_SECI (1<<1)
+#define CCTRL4331_EXT_LNA_G (1<<2)
+#define CCTRL4331_SPROM_GPIO13_15 (1<<3)
+#define CCTRL4331_EXTPA_EN (1<<4)
+#define CCTRL4331_GPIOCLK_ON_SPROMCS <1<<5)
+#define CCTRL4331_PCIE_MDIO_ON_SPROMCS (1<<6)
+#define CCTRL4331_EXTPA_ON_GPIO2_5 (1<<7)
+#define CCTRL4331_OVR_PIPEAUXCLKEN (1<<8)
+#define CCTRL4331_OVR_PIPEAUXPWRDOWN (1<<9)
+#define CCTRL4331_PCIE_AUXCLKEN <1<<10)
+#define CCTRL4331_PCIE_PIPE_PLLDOWN <1<<11)
+#define CCTRL4331_EXTPA_EN2 (1<<12)
+#define CCTRL4331_EXT_LNA_A (1<<13)
+#define CCTRL4331_BT_SHD0_ON_GPIO4 <1<<16)
+#define CCTRL4331_BT_SHD1_ON_GPIO5 <1<<17)
+#define CCTRL4331_EXTPA_ANA_EN (1<<24)
+
+
+#define CST4331_XTAL_FREQ 0x00000001
+#define CST4331_SPROM_OTP_SEL_MASK 0x00000006
+#define CST4331_SPROM_OTP_SEL_SHIFT 1
+#define CST4331_SPROM_PRESENT 0x00000002
+#define CST4331_OTP_PRESENT 0x00000004
+#define CST4331_LDO_RF 0x00000008
+#define CST4331_LDO_PAR 0x00000010
#define RES4315_CBUCK_LPOM 1
@@ -1597,6 +1709,54 @@
+#define SECI_MODE_UART 0x0
+#define SECI_MODE_SECI 0x1
+#define SECI_MODE_LEGACY_3WIRE_BT 0x2
+#define SECI_MODE_LEGACY_3WIRE_WLAN 0x3
+#define SECI_MODE_HALF_SECI 0x4
+
+#define SECI_RESET (1 << 0)
+#define SECI_RESET_BAR_UART (1 << 1)
+#define SECI_ENAB_SECI_ECI (1 << 2)
+#define SECI_ENAB_SECIOUT_DIS (1 << 3)
+#define SECI_MODE_MASK 0x7
+#define SECI_MODE_SHIFT 4
+#define SECI_UPD_SECI (1 << 7)
+
+
+#define CLKCTL_STS_SECI_CLK_REQ (1 << 8)
+#define CLKCTL_STS_SECI_CLK_AVAIL (1 << 24)
+
+#define SECI_UART_MSR_CTS_STATE (1 << 0)
+#define SECI_UART_MSR_RTS_STATE (1 << 1)
+#define SECI_UART_SECI_IN_STATE (1 << 2)
+#define SECI_UART_SECI_IN2_STATE (1 << 3)
+
+
+#define SECI_UART_LCR_STOP_BITS (1 << 0)
+#define SECI_UART_LCR_PARITY_EN (1 << 1)
+#define SECI_UART_LCR_PARITY (1 << 2)
+#define SECI_UART_LCR_RX_EN (1 << 3)
+#define SECI_UART_LCR_LBRK_CTRL (1 << 4)
+#define SECI_UART_LCR_TXO_EN (1 << 5)
+#define SECI_UART_LCR_RTSO_EN (1 << 6)
+#define SECI_UART_LCR_SLIPMODE_EN (1 << 7)
+#define SECI_UART_LCR_RXCRC_CHK (1 << 8)
+#define SECI_UART_LCR_TXCRC_INV (1 << 9)
+#define SECI_UART_LCR_TXCRC_LSBF (1 << 10)
+#define SECI_UART_LCR_TXCRC_EN (1 << 11)
+
+#define SECI_UART_MCR_TX_EN (1 << 0)
+#define SECI_UART_MCR_PRTS (1 << 1)
+#define SECI_UART_MCR_SWFLCTRL_EN (1 << 2)
+#define SECI_UART_MCR_HIGHRATE_EN (1 << 3)
+#define SECI_UART_MCR_LOOPBK_EN (1 << 4)
+#define SECI_UART_MCR_AUTO_RTS (1 << 5)
+#define SECI_UART_MCR_AUTO_TX_DIS (1 << 6)
+#define SECI_UART_MCR_BAUD_ADJ_EN (1 << 7)
+#define SECI_UART_MCR_XONOFF_RPT (1 << 9)
+
+
#define ECI_BW_20 0x0
diff --git a/drivers/net/wireless/bcmdhd/include/sbconfig.h b/drivers/net/wireless/bcmdhd/include/sbconfig.h
index 76f05ae..f45351a 100644
--- a/drivers/net/wireless/bcmdhd/include/sbconfig.h
+++ b/drivers/net/wireless/bcmdhd/include/sbconfig.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: sbconfig.h,v 13.70 2008-03-28 19:17:04 Exp $
+ * $Id: sbconfig.h 277737 2011-08-16 17:54:59Z $
*/
diff --git a/drivers/net/wireless/bcmdhd/include/sbhnddma.h b/drivers/net/wireless/bcmdhd/include/sbhnddma.h
index 05d0587..77c413f 100644
--- a/drivers/net/wireless/bcmdhd/include/sbhnddma.h
+++ b/drivers/net/wireless/bcmdhd/include/sbhnddma.h
@@ -22,7 +22,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: sbhnddma.h,v 13.20.2.3 2010-10-14 22:21:29 Exp $
+ * $Id: sbhnddma.h 278779 2011-08-19 22:07:18Z $
*/
@@ -217,7 +217,7 @@
#define D64_XC_BL_SHIFT 18
-#define D64_XP_LD_MASK 0x00000fff
+#define D64_XP_LD_MASK 0x00001fff
#define D64_XS0_CD_MASK 0x00001fff
@@ -260,7 +260,7 @@
#define DMA_CTRL_USB_BOUNDRY4KB_WAR (1 << 4)
-#define D64_RP_LD_MASK 0x00000fff
+#define D64_RP_LD_MASK 0x00001fff
#define D64_RS0_CD_MASK 0x00001fff
diff --git a/drivers/net/wireless/bcmdhd/include/sbpcmcia.h b/drivers/net/wireless/bcmdhd/include/sbpcmcia.h
index aba914b..d84f69a 100644
--- a/drivers/net/wireless/bcmdhd/include/sbpcmcia.h
+++ b/drivers/net/wireless/bcmdhd/include/sbpcmcia.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: sbpcmcia.h,v 13.48.12.6 2010-11-04 09:39:42 Exp $
+ * $Id: sbpcmcia.h 277737 2011-08-16 17:54:59Z $
*/
diff --git a/drivers/net/wireless/bcmdhd/include/sbsdio.h b/drivers/net/wireless/bcmdhd/include/sbsdio.h
index 4280d5b..7aaeb73 100644
--- a/drivers/net/wireless/bcmdhd/include/sbsdio.h
+++ b/drivers/net/wireless/bcmdhd/include/sbsdio.h
@@ -24,7 +24,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: sbsdio.h,v 13.34 2009-03-11 20:27:16 Exp $
+ * $Id: sbsdio.h 277737 2011-08-16 17:54:59Z $
*/
#ifndef _SBSDIO_H
diff --git a/drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h b/drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h
index 107a8b0..e517648 100644
--- a/drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h
+++ b/drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h
@@ -22,7 +22,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: sbsdpcmdev.h,v 13.38 2009-09-22 22:56:45 Exp $
+ * $Id: sbsdpcmdev.h 282638 2011-09-08 21:18:10Z $
*/
#ifndef _sbsdpcmdev_h_
diff --git a/drivers/net/wireless/bcmdhd/include/sbsocram.h b/drivers/net/wireless/bcmdhd/include/sbsocram.h
index 1cba422..45c4dc2 100644
--- a/drivers/net/wireless/bcmdhd/include/sbsocram.h
+++ b/drivers/net/wireless/bcmdhd/include/sbsocram.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: sbsocram.h,v 13.15 2009-10-02 16:55:44 Exp $
+ * $Id: sbsocram.h 277737 2011-08-16 17:54:59Z $
*/
diff --git a/drivers/net/wireless/bcmdhd/include/sdio.h b/drivers/net/wireless/bcmdhd/include/sdio.h
index ca93226..c8ac7b7 100644
--- a/drivers/net/wireless/bcmdhd/include/sdio.h
+++ b/drivers/net/wireless/bcmdhd/include/sdio.h
@@ -22,7 +22,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: sdio.h,v 13.27.14.1 2010-09-07 13:37:45 Exp $
+ * $Id: sdio.h 277737 2011-08-16 17:54:59Z $
*/
#ifndef _SDIO_H
@@ -366,7 +366,7 @@
* SDIO Commands and responses
*
* I/O only commands are:
- * CMD0, CMD3, CMD5, CMD7, CMD15, CMD52, CMD53
+ * CMD0, CMD3, CMD5, CMD7, CMD14, CMD15, CMD52, CMD53
* ------------------------------------------------
*/
@@ -412,6 +412,7 @@
#define CMD7_RCA_M BITFIELD_MASK(16)
#define CMD7_RCA_S 16
+
#define CMD14_RCA_M BITFIELD_MASK(16)
#define CMD14_RCA_S 16
#define CMD14_SLEEP_M BITFIELD_MASK(1)
diff --git a/drivers/net/wireless/bcmdhd/include/sdioh.h b/drivers/net/wireless/bcmdhd/include/sdioh.h
index 3d37c7a..5f47d6f 100644
--- a/drivers/net/wireless/bcmdhd/include/sdioh.h
+++ b/drivers/net/wireless/bcmdhd/include/sdioh.h
@@ -22,7 +22,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: sdioh.h,v 13.17.2.3 2011-01-08 05:28:21 Exp $
+ * $Id: sdioh.h 300017 2011-12-01 20:30:27Z $
*/
#ifndef _SDIOH_H
@@ -68,6 +68,10 @@
#define SD_ADMA_SysAddr 0x58
#define SD_SlotInterruptStatus 0x0FC
#define SD_HostControllerVersion 0x0FE
+#define SD_GPIO_Reg 0x100
+#define SD_GPIO_OE 0x104
+#define SD_GPIO_Enable 0x108
+
/* SD specific registers in PCI config space */
#define SD_SlotInfo 0x40
@@ -409,4 +413,30 @@
/* SD_SlotInterruptStatus: Offset 0x0FC , size = bytes */
/* SD_HostControllerVersion : Offset 0x0FE , size = bytes */
+/* SDIO Host Control Register DMA Mode Definitions */
+#define SDIOH_SDMA_MODE 0
+#define SDIOH_ADMA1_MODE 1
+#define SDIOH_ADMA2_MODE 2
+#define SDIOH_ADMA2_64_MODE 3
+
+#define ADMA2_ATTRIBUTE_VALID (1 << 0) /* ADMA Descriptor line valid */
+#define ADMA2_ATTRIBUTE_END (1 << 1) /* End of Descriptor */
+#define ADMA2_ATTRIBUTE_INT (1 << 2) /* Interrupt when line is done */
+#define ADMA2_ATTRIBUTE_ACT_NOP (0 << 4) /* Skip current line, go to next. */
+#define ADMA2_ATTRIBUTE_ACT_RSV (1 << 4) /* Same as NOP */
+#define ADMA1_ATTRIBUTE_ACT_SET (1 << 4) /* ADMA1 Only - set transfer length */
+#define ADMA2_ATTRIBUTE_ACT_TRAN (2 << 4) /* Transfer Data of one descriptor line. */
+#define ADMA2_ATTRIBUTE_ACT_LINK (3 << 4) /* Link Descriptor */
+
+/* ADMA2 Descriptor Table Entry for 32-bit Address */
+typedef struct adma2_dscr_32b {
+ uint32 len_attr;
+ uint32 phys_addr;
+} adma2_dscr_32b_t;
+
+/* ADMA1 Descriptor Table Entry */
+typedef struct adma1_dscr {
+ uint32 phys_addr_attr;
+} adma1_dscr_t;
+
#endif /* _SDIOH_H */
diff --git a/drivers/net/wireless/bcmdhd/include/sdiovar.h b/drivers/net/wireless/bcmdhd/include/sdiovar.h
index 2c5bcf9..55a3d34 100644
--- a/drivers/net/wireless/bcmdhd/include/sdiovar.h
+++ b/drivers/net/wireless/bcmdhd/include/sdiovar.h
@@ -22,7 +22,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: sdiovar.h,v 13.9 2009-12-08 22:30:15 Exp $
+ * $Id: sdiovar.h 277737 2011-08-16 17:54:59Z $
*/
#ifndef _sdiovar_h_
diff --git a/drivers/net/wireless/bcmdhd/include/siutils.h b/drivers/net/wireless/bcmdhd/include/siutils.h
index c5a3383..6a7b93c 100644
--- a/drivers/net/wireless/bcmdhd/include/siutils.h
+++ b/drivers/net/wireless/bcmdhd/include/siutils.h
@@ -22,7 +22,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: siutils.h,v 13.251.2.10 2011-02-04 05:06:32 Exp $
+ * $Id: siutils.h 285387 2011-09-21 18:38:37Z $
*/
@@ -60,6 +60,7 @@
typedef const struct si_pub si_t;
+
#define SI_OSH NULL
#define BADIDX (SI_MAXCORES + 1)
@@ -213,8 +214,34 @@
#define si_eci(sih) 0
#define si_eci_init(sih) (0)
#define si_eci_notify_bt(sih, type, val) (0)
+#define si_seci(sih) 0
+static INLINE void * si_seci_init(si_t *sih, uint8 use_seci) {return NULL;}
+#define si_seci_down(sih) do { } while (0)
+extern bool si_is_otp_disabled(si_t *sih);
+extern bool si_is_otp_powered(si_t *sih);
+extern void si_otp_power(si_t *sih, bool on);
+
+
+extern bool si_is_sprom_available(si_t *sih);
+extern bool si_is_sprom_enabled(si_t *sih);
+extern void si_sprom_enable(si_t *sih, bool enable);
+
+
+extern int si_cis_source(si_t *sih);
+#define CIS_DEFAULT 0
+#define CIS_SROM 1
+#define CIS_OTP 2
+
+
+#define DEFAULT_FAB 0x0
+#define CSM_FAB7 0x1
+#define TSMC_FAB12 0x2
+#define SMIC_FAB4 0x3
+extern int si_otp_fabid(si_t *sih, uint16 *fabid, bool rw);
+extern uint16 si_fabid(si_t *sih);
+
extern int si_devpath(si_t *sih, char *path, int size);
@@ -244,4 +271,5 @@
char *si_getnvramflvar(si_t *sih, const char *name);
+
#endif
diff --git a/drivers/net/wireless/bcmdhd/include/trxhdr.h b/drivers/net/wireless/bcmdhd/include/trxhdr.h
index 397006a..b52fb15 100644
--- a/drivers/net/wireless/bcmdhd/include/trxhdr.h
+++ b/drivers/net/wireless/bcmdhd/include/trxhdr.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: trxhdr.h,v 13.15.108.2 2010-11-15 17:57:30 Exp $
+ * $Id: trxhdr.h 286295 2011-09-27 06:39:43Z $
*/
#ifndef _TRX_HDR_H_
@@ -37,6 +37,7 @@
#define TRX_OVERLAYS 0x4 /* Contains an overlay header after the trx header */
#define TRX_MAX_OFFSET 3 /* Max number of individual files */
#define TRX_UNCOMP_IMAGE 0x20 /* Trx contains uncompressed rtecdc.bin image */
+#define TRX_ROMSIM_IMAGE 0x10 /* Trx contains ROM simulation image */
struct trx_header {
uint32 magic; /* "HDR0" */
diff --git a/drivers/net/wireless/bcmdhd/include/typedefs.h b/drivers/net/wireless/bcmdhd/include/typedefs.h
index 228b5dc..d0902fe 100644
--- a/drivers/net/wireless/bcmdhd/include/typedefs.h
+++ b/drivers/net/wireless/bcmdhd/include/typedefs.h
@@ -18,7 +18,7 @@
* Notwithstanding the above, under no circumstances may you combine this
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
- * $Id: typedefs.h,v 1.103.2.1 2010-05-11 18:19:28 Exp $
+ * $Id: typedefs.h 290055 2011-10-15 21:26:26Z $
*/
@@ -305,5 +305,8 @@
#define UNUSED_PARAMETER(x) (void)(x)
+#define DISCARD_QUAL(ptr, type) ((type *)(uintptr)(ptr))
+
+
#include <bcmdefs.h>
#endif
diff --git a/drivers/net/wireless/bcmdhd/include/wlfc_proto.h b/drivers/net/wireless/bcmdhd/include/wlfc_proto.h
index 7230d3b..d371051 100644
--- a/drivers/net/wireless/bcmdhd/include/wlfc_proto.h
+++ b/drivers/net/wireless/bcmdhd/include/wlfc_proto.h
@@ -18,7 +18,7 @@
* Notwithstanding the above, under no circumstances may you combine this
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
-* $Id: wlfc_proto.h,v 1.1.6.2 2010-05-08 01:30:41 Exp $
+* $Id: wlfc_proto.h 277737 2011-08-16 17:54:59Z $
*
*/
#ifndef __wlfc_proto_definitions_h__
diff --git a/drivers/net/wireless/bcmdhd/include/wlioctl.h b/drivers/net/wireless/bcmdhd/include/wlioctl.h
index 9357552..e31bfa9 100644
--- a/drivers/net/wireless/bcmdhd/include/wlioctl.h
+++ b/drivers/net/wireless/bcmdhd/include/wlioctl.h
@@ -24,7 +24,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: wlioctl.h,v 1.767.2.38 2011-02-01 23:04:28 Exp $
+ * $Id: wlioctl.h 307468 2012-01-11 18:29:27Z $
*/
@@ -65,8 +65,8 @@
typedef struct ssid_info
{
- uint8 ssid_len;
- uint8 ssid[32];
+ uint8 ssid_len;
+ uint8 ssid[32];
} ssid_info_t;
typedef struct wl_af_params {
@@ -191,6 +191,7 @@
#define WL_SCANFLAGS_PROHIBITED 0x04
#define WL_SCAN_PARAMS_SSID_MAX 10
+
typedef struct wl_scan_params {
wlc_ssid_t ssid;
struct ether_addr bssid;
@@ -376,6 +377,8 @@
#define NRATE_SGI_SHIFT 23
#define NRATE_LDPC_CODING 0x00400000
#define NRATE_LDPC_SHIFT 22
+#define NRATE_BCMC_OVERRIDE 0x00200000
+#define NRATE_BCMC_SHIFT 21
#define NRATE_STF_SISO 0
#define NRATE_STF_CDD 1
@@ -555,7 +558,7 @@
#define CRYPTO_ALGO_AES_OCB_MSDU 5
#define CRYPTO_ALGO_AES_OCB_MPDU 6
#define CRYPTO_ALGO_NALG 7
-#define CRYPTO_ALGO_PMK 12
+#define CRYPTO_ALGO_PMK 12
#define WSEC_GEN_MIC_ERROR 0x0001
#define WSEC_GEN_REPLAY 0x0002
@@ -617,9 +620,9 @@
#define WPA2_AUTH_PSK 0x0080
#define BRCM_AUTH_PSK 0x0100
#define BRCM_AUTH_DPT 0x0200
-#define WPA2_AUTH_MFP 0x1000
-#define WPA2_AUTH_TPK 0x2000
-#define WPA2_AUTH_FT 0x4000
+#define WPA2_AUTH_MFP 0x1000
+#define WPA2_AUTH_TPK 0x2000
+#define WPA2_AUTH_FT 0x4000
#define MAXPMKID 16
@@ -649,12 +652,12 @@
uint32 resp_len;
uint32 flags;
struct dot11_assoc_req req;
- struct ether_addr reassoc_bssid;
+ struct ether_addr reassoc_bssid;
struct dot11_assoc_resp resp;
} wl_assoc_info_t;
-#define WLC_ASSOC_REQ_IS_REASSOC 0x01
+#define WLC_ASSOC_REQ_IS_REASSOC 0x01
typedef struct {
@@ -818,8 +821,14 @@
#define WLC_IOCTL_MEDLEN 1536
#ifdef WLC_HIGH_ONLY
#define WLC_SAMPLECOLLECT_MAXLEN 1024
+#define WLC_SAMPLECOLLECT_MAXLEN_LCN40 1024
#else
-#define WLC_SAMPLECOLLECT_MAXLEN 10240
+#if defined(LCNCONF) || defined(LCN40CONF)
+#define WLC_SAMPLECOLLECT_MAXLEN 8192
+#else
+#define WLC_SAMPLECOLLECT_MAXLEN 10240
+#endif
+#define WLC_SAMPLECOLLECT_MAXLEN_LCN40 8192
#endif
@@ -851,6 +860,7 @@
#define WLC_GET_SSID 25
#define WLC_SET_SSID 26
#define WLC_RESTART 27
+#define WLC_TERMINATED 28
#define WLC_GET_CHANNEL 29
#define WLC_SET_CHANNEL 30
@@ -1203,7 +1213,7 @@
#define WL_AUTH_OPEN_SYSTEM 0
#define WL_AUTH_SHARED_KEY 1
-#define WL_AUTH_OPEN_SHARED 2
+#define WL_AUTH_OPEN_SHARED 3
#define WL_RADIO_SW_DISABLE (1<<0)
@@ -1280,18 +1290,17 @@
#define WL_CHAN_FREQ_RANGE_5GM 2
#define WL_CHAN_FREQ_RANGE_5GH 3
-#define WL_CHAN_FREQ_RANGE_5GLL_VER2 4
-#define WL_CHAN_FREQ_RANGE_5GLH_VER2 5
-#define WL_CHAN_FREQ_RANGE_5GML_VER2 6
-#define WL_CHAN_FREQ_RANGE_5GMH_VER2 7
-#define WL_CHAN_FREQ_RANGE_5GH_VER2 8
-
#define WL_CHAN_FREQ_RANGE_5GLL_5BAND 4
#define WL_CHAN_FREQ_RANGE_5GLH_5BAND 5
#define WL_CHAN_FREQ_RANGE_5GML_5BAND 6
#define WL_CHAN_FREQ_RANGE_5GMH_5BAND 7
#define WL_CHAN_FREQ_RANGE_5GH_5BAND 8
+#define WL_CHAN_FREQ_RANGE_5G_BAND0 1
+#define WL_CHAN_FREQ_RANGE_5G_BAND1 2
+#define WL_CHAN_FREQ_RANGE_5G_BAND2 3
+#define WL_CHAN_FREQ_RANGE_5G_BAND3 4
+
#define WLC_PHY_TYPE_A 0
#define WLC_PHY_TYPE_B 1
@@ -1363,7 +1372,7 @@
#define PM_MAX 1
#define PM_FAST 2
-#define LISTEN_INTERVAL 10
+#define LISTEN_INTERVAL 10
#define INTERFERE_OVRRIDE_OFF -1
#define INTERFERE_NONE 0
@@ -1408,7 +1417,7 @@
#define TRIGGER_BADPLCP 0x10
#define TRIGGER_CRSGLITCH 0x20
#define WL_ACI_ARGS_LEGACY_LENGTH 16
-#define WL_SAMPLECOLLECT_T_VERSION 1
+#define WL_SAMPLECOLLECT_T_VERSION 2
typedef struct wl_samplecollect_args {
uint8 coll_us;
@@ -1416,7 +1425,7 @@
uint16 version;
uint16 length;
- uint8 trigger;
+ int8 trigger;
uint16 timeout;
uint16 mode;
uint32 pre_dur;
@@ -1426,6 +1435,11 @@
bool be_deaf;
bool agc;
bool filter;
+
+ uint8 trigger_state;
+ uint8 module_sel1;
+ uint8 module_sel2;
+ uint16 nsamps;
} wl_samplecollect_args_t;
#define WL_SAMPLEDATA_HEADER_TYPE 1
@@ -1493,6 +1507,7 @@
#define WL_P2P_VAL 0x00000200
#define WL_TXRX_VAL 0x00000400
#define WL_MCHAN_VAL 0x00000800
+#define WL_TDLS_VAL 0x00001000
#define WL_LED_NUMGPIO 16
@@ -1546,7 +1561,7 @@
#define WL_JOIN_PREF_WPA 2
#define WL_JOIN_PREF_BAND 3
#define WL_JOIN_PREF_RSSI_DELTA 4
-#define WL_JOIN_PREF_TRANS_PREF 5
+#define WL_JOIN_PREF_TRANS_PREF 5
#define WLJP_BAND_ASSOC_PREF 255
@@ -1797,17 +1812,19 @@
};
typedef struct wl_mkeep_alive_pkt {
- uint16 version;
- uint16 length;
+ uint16 version;
+ uint16 length;
uint32 period_msec;
uint16 len_bytes;
- uint8 keep_alive_id;
+ uint8 keep_alive_id;
uint8 data[1];
} wl_mkeep_alive_pkt_t;
-#define WL_MKEEP_ALIVE_VERSION 1
-#define WL_MKEEP_ALIVE_FIXED_LEN OFFSETOF(wl_mkeep_alive_pkt_t, data)
-#define WL_MKEEP_ALIVE_PRECISION 500
+#define WL_MKEEP_ALIVE_VERSION 1
+#define WL_MKEEP_ALIVE_FIXED_LEN OFFSETOF(wl_mkeep_alive_pkt_t, data)
+#define WL_MKEEP_ALIVE_PRECISION 500
+
+
#define WLC_ROAM_TRIGGER_DEFAULT 0
#define WLC_ROAM_TRIGGER_BANDWIDTH 1
@@ -1897,7 +1914,7 @@
uint8 mscan;
uint8 repeat;
uint8 exp;
- int32 slow_freq;
+ int32 slow_freq;
} wl_pfn_param_t;
typedef struct wl_pfn_bssid {
@@ -2016,8 +2033,31 @@
+#define MAX_WAKE_PACKET_BYTES 128
+
+
+typedef struct pm_wake_packet {
+ uint32 status;
+ uint32 pattern_id;
+ uint32 original_packet_size;
+ uint32 saved_packet_size;
+ uchar packet[MAX_WAKE_PACKET_BYTES];
+} pm_wake_packet_t;
+
+
+
+#define PKT_FILTER_MODE_FORWARD_ON_MATCH 1
+
+#define PKT_FILTER_MODE_DISABLE 2
+
+#define PKT_FILTER_MODE_PKT_CACHE_ON_MATCH 4
+
+#define PKT_FILTER_MODE_PKT_FORWARD_OFF_DEFAULT 8
+
+
typedef enum wl_pkt_filter_type {
- WL_PKT_FILTER_TYPE_PATTERN_MATCH
+ WL_PKT_FILTER_TYPE_PATTERN_MATCH,
+ WL_PKT_FILTER_TYPE_MAGIC_PATTERN_MATCH
} wl_pkt_filter_type_t;
#define WL_PKT_FILTER_TYPE wl_pkt_filter_type_t
@@ -2550,6 +2590,12 @@
#define WL_PHYCAL_STAT_FIXED_LEN OFFSETOF(wl_phycal_state_t, phycal_core)
#endif
+#ifdef WLDSTA
+typedef struct wl_dsta_if {
+ struct ether_addr addr;
+} wl_dsta_if_t;
+#endif
+
#ifdef WLP2P
typedef struct wl_p2p_disc_st {
diff --git a/drivers/net/wireless/bcmdhd/linux_osl.c b/drivers/net/wireless/bcmdhd/linux_osl.c
index 1a54437..4ef7bf7 100644
--- a/drivers/net/wireless/bcmdhd/linux_osl.c
+++ b/drivers/net/wireless/bcmdhd/linux_osl.c
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: linux_osl.c,v 1.168.2.7 2011-01-27 17:01:13 Exp $
+ * $Id: linux_osl.c,v 1.168.2.7 2011-01-27 17:01:13 $
*/
@@ -47,7 +47,7 @@
#define OS_HANDLE_MAGIC 0x1234abcd
#define BCM_MEM_FILENAME_LEN 24
-#ifdef DHD_USE_STATIC_BUF
+#ifdef CONFIG_DHD_USE_STATIC_BUF
#define STATIC_BUF_MAX_NUM 16
#define STATIC_BUF_SIZE (PAGE_SIZE * 2)
#define STATIC_BUF_TOTAL_LEN (STATIC_BUF_MAX_NUM * STATIC_BUF_SIZE)
@@ -70,7 +70,7 @@
} bcm_static_pkt_t;
static bcm_static_pkt_t *bcm_static_skb = 0;
-#endif
+#endif
typedef struct bcm_mem_link {
struct bcm_mem_link *prev;
@@ -211,7 +211,7 @@
break;
}
-#if defined(DHD_USE_STATIC_BUF)
+#if defined(CONFIG_DHD_USE_STATIC_BUF)
if (!bcm_static_buf) {
if (!(bcm_static_buf = (bcm_static_buf_t *)dhd_os_prealloc(osh, 3, STATIC_BUF_SIZE+
STATIC_BUF_TOTAL_LEN))) {
@@ -220,7 +220,6 @@
else
printk("alloc static buf at %x!\n", (unsigned int)bcm_static_buf);
-
sema_init(&bcm_static_buf->static_sem, 1);
bcm_static_buf->buf_ptr = (unsigned char *)bcm_static_buf + STATIC_BUF_SIZE;
@@ -238,7 +237,7 @@
sema_init(&bcm_static_skb->osl_pkt_sem, 1);
}
-#endif
+#endif
return osh;
}
@@ -388,7 +387,7 @@
if ((osh == NULL) || (osh->ctfpool == NULL))
return;
-#ifdef DHD_USE_STATIC_BUF
+#ifdef CONFIG_DHD_USE_STATIC_BUF
if (bcm_static_buf) {
bcm_static_buf = 0;
}
@@ -548,14 +547,14 @@
}
}
-#ifdef DHD_USE_STATIC_BUF
+#ifdef CONFIG_DHD_USE_STATIC_BUF
void *
osl_pktget_static(osl_t *osh, uint len)
{
int i;
struct sk_buff *skb;
- if (len > (PAGE_SIZE * 2)) {
+ if (!bcm_static_skb || (len > (PAGE_SIZE * 2))) {
printk("%s: attempt to allocate huge packet (0x%x)\n", __FUNCTION__, len);
return osl_pktget(osh, len);
}
@@ -570,10 +569,10 @@
if (i != STATIC_PKT_MAX_NUM) {
bcm_static_skb->pkt_use[i] = 1;
- up(&bcm_static_skb->osl_pkt_sem);
skb = bcm_static_skb->skb_4k[i];
skb->tail = skb->data + len;
skb->len = len;
+ up(&bcm_static_skb->osl_pkt_sem);
return skb;
}
}
@@ -586,10 +585,10 @@
if (i != STATIC_PKT_MAX_NUM) {
bcm_static_skb->pkt_use[i+STATIC_PKT_MAX_NUM] = 1;
- up(&bcm_static_skb->osl_pkt_sem);
skb = bcm_static_skb->skb_8k[i];
skb->tail = skb->data + len;
skb->len = len;
+ up(&bcm_static_skb->osl_pkt_sem);
return skb;
}
@@ -603,9 +602,14 @@
{
int i;
+ if (!bcm_static_skb) {
+ osl_pktfree(osh, p, send);
+ return;
+ }
+
+ down(&bcm_static_skb->osl_pkt_sem);
for (i = 0; i < STATIC_PKT_MAX_NUM; i++) {
if (p == bcm_static_skb->skb_4k[i]) {
- down(&bcm_static_skb->osl_pkt_sem);
bcm_static_skb->pkt_use[i] = 0;
up(&bcm_static_skb->osl_pkt_sem);
return;
@@ -614,14 +618,15 @@
for (i = 0; i < STATIC_PKT_MAX_NUM; i++) {
if (p == bcm_static_skb->skb_8k[i]) {
- down(&bcm_static_skb->osl_pkt_sem);
bcm_static_skb->pkt_use[i + STATIC_PKT_MAX_NUM] = 0;
up(&bcm_static_skb->osl_pkt_sem);
return;
}
}
+ up(&bcm_static_skb->osl_pkt_sem);
- return osl_pktfree(osh, p, send);
+ osl_pktfree(osh, p, send);
+ return;
}
#endif
diff --git a/drivers/net/wireless/bcmdhd/siutils.c b/drivers/net/wireless/bcmdhd/siutils.c
index 22aa412..a655ac4 100644
--- a/drivers/net/wireless/bcmdhd/siutils.c
+++ b/drivers/net/wireless/bcmdhd/siutils.c
@@ -22,7 +22,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: siutils.c,v 1.813.2.36 2011-02-10 23:43:55 Exp $
+ * $Id: siutils.c,v 1.813.2.36 2011-02-10 23:43:55 $
*/
#include <typedefs.h>
@@ -213,11 +213,11 @@
/* figure out bus/orignal core idx */
sii->pub.buscoretype = NODEV_CORE_ID;
- sii->pub.buscorerev = NOREV;
+ sii->pub.buscorerev = (uint)NOREV;
sii->pub.buscoreidx = BADIDX;
pci = pcie = FALSE;
- pcirev = pcierev = NOREV;
+ pcirev = pcierev = (uint)NOREV;
pciidx = pcieidx = BADIDX;
for (i = 0; i < sii->numcores; i++) {
@@ -365,6 +365,19 @@
return NULL;
}
+#if defined(HW_OOB)
+ if (CHIPID(sih->chip) == BCM43362_CHIP_ID) {
+ uint32 gpiocontrol, addr;
+ addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, gpiocontrol);
+ gpiocontrol = bcmsdh_reg_read(sdh, addr, 4);
+ gpiocontrol |= 0x2;
+ bcmsdh_reg_write(sdh, addr, 4, gpiocontrol);
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10005, 0xf, NULL);
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10006, 0x0, NULL);
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10007, 0x2, NULL);
+ }
+#endif
+
if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) && (sih->chiprev == 0) &&
(sih->chippkg != BCM4329_289PIN_PKG_ID)) {
sih->chippkg = BCM4329_182PIN_PKG_ID;
@@ -401,8 +414,9 @@
}
/* assume current core is CC */
- if ((sii->pub.ccrev == 0x25) && ((CHIPID(sih->chip) == BCM43236_CHIP_ID ||
+ if ((sii->pub.ccrev == 0x25) && ((CHIPID(sih->chip) == BCM43234_CHIP_ID ||
CHIPID(sih->chip) == BCM43235_CHIP_ID ||
+ CHIPID(sih->chip) == BCM43236_CHIP_ID ||
CHIPID(sih->chip) == BCM43238_CHIP_ID) &&
(CHIPREV(sii->pub.chiprev) == 0))) {
@@ -1093,6 +1107,126 @@
+/* return the slow clock source - LPO, XTAL, or PCI */
+static uint
+si_slowclk_src(si_info_t *sii)
+{
+ chipcregs_t *cc;
+
+ ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID);
+
+ if (sii->pub.ccrev < 6) {
+ if ((BUSTYPE(sii->pub.bustype) == PCI_BUS) &&
+ (OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_OUT, sizeof(uint32)) &
+ PCI_CFG_GPIO_SCS))
+ return (SCC_SS_PCI);
+ else
+ return (SCC_SS_XTAL);
+ } else if (sii->pub.ccrev < 10) {
+ cc = (chipcregs_t *)si_setcoreidx(&sii->pub, sii->curidx);
+ return (R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_SS_MASK);
+ } else /* Insta-clock */
+ return (SCC_SS_XTAL);
+}
+
+/* return the ILP (slowclock) min or max frequency */
+static uint
+si_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc)
+{
+ uint32 slowclk;
+ uint div;
+
+ ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID);
+
+ /* shouldn't be here unless we've established the chip has dynamic clk control */
+ ASSERT(R_REG(sii->osh, &cc->capabilities) & CC_CAP_PWR_CTL);
+
+ slowclk = si_slowclk_src(sii);
+ if (sii->pub.ccrev < 6) {
+ if (slowclk == SCC_SS_PCI)
+ return (max_freq ? (PCIMAXFREQ / 64) : (PCIMINFREQ / 64));
+ else
+ return (max_freq ? (XTALMAXFREQ / 32) : (XTALMINFREQ / 32));
+ } else if (sii->pub.ccrev < 10) {
+ div = 4 *
+ (((R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1);
+ if (slowclk == SCC_SS_LPO)
+ return (max_freq ? LPOMAXFREQ : LPOMINFREQ);
+ else if (slowclk == SCC_SS_XTAL)
+ return (max_freq ? (XTALMAXFREQ / div) : (XTALMINFREQ / div));
+ else if (slowclk == SCC_SS_PCI)
+ return (max_freq ? (PCIMAXFREQ / div) : (PCIMINFREQ / div));
+ else
+ ASSERT(0);
+ } else {
+ /* Chipc rev 10 is InstaClock */
+ div = R_REG(sii->osh, &cc->system_clk_ctl) >> SYCC_CD_SHIFT;
+ div = 4 * (div + 1);
+ return (max_freq ? XTALMAXFREQ : (XTALMINFREQ / div));
+ }
+ return (0);
+}
+
+static void
+si_clkctl_setdelay(si_info_t *sii, void *chipcregs)
+{
+ chipcregs_t *cc = (chipcregs_t *)chipcregs;
+ uint slowmaxfreq, pll_delay, slowclk;
+ uint pll_on_delay, fref_sel_delay;
+
+ pll_delay = PLL_DELAY;
+
+ /* If the slow clock is not sourced by the xtal then add the xtal_on_delay
+ * since the xtal will also be powered down by dynamic clk control logic.
+ */
+
+ slowclk = si_slowclk_src(sii);
+ if (slowclk != SCC_SS_XTAL)
+ pll_delay += XTAL_ON_DELAY;
+
+ /* Starting with 4318 it is ILP that is used for the delays */
+ slowmaxfreq = si_slowclk_freq(sii, (sii->pub.ccrev >= 10) ? FALSE : TRUE, cc);
+
+ pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
+ fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
+
+ W_REG(sii->osh, &cc->pll_on_delay, pll_on_delay);
+ W_REG(sii->osh, &cc->fref_sel_delay, fref_sel_delay);
+}
+
+/* initialize power control delay registers */
+void
+si_clkctl_init(si_t *sih)
+{
+ si_info_t *sii;
+ uint origidx = 0;
+ chipcregs_t *cc;
+ bool fast;
+
+ if (!CCCTL_ENAB(sih))
+ return;
+
+ sii = SI_INFO(sih);
+ fast = SI_FAST(sii);
+ if (!fast) {
+ origidx = sii->curidx;
+ if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL)
+ return;
+ } else if ((cc = (chipcregs_t *)CCREGS_FAST(sii)) == NULL)
+ return;
+ ASSERT(cc != NULL);
+
+ /* set all Instaclk chip ILP to 1 MHz */
+ if (sih->ccrev >= 10)
+ SET_REG(sii->osh, &cc->system_clk_ctl, SYCC_CD_MASK,
+ (ILP_DIV_1MHZ << SYCC_CD_SHIFT));
+
+ si_clkctl_setdelay(sii, (void *)(uintptr)cc);
+
+ if (!fast)
+ si_setcoreidx(sih, origidx);
+}
+
/* change logical "focus" to the gpio core for optimized access */
void *
si_gpiosetcore(si_t *sih)
@@ -1718,3 +1852,64 @@
}
return FALSE;
}
+
+bool
+si_is_sprom_available(si_t *sih)
+{
+ if (sih->ccrev >= 31) {
+ si_info_t *sii;
+ uint origidx;
+ chipcregs_t *cc;
+ uint32 sromctrl;
+
+ if ((sih->cccaps & CC_CAP_SROM) == 0)
+ return FALSE;
+
+ sii = SI_INFO(sih);
+ origidx = sii->curidx;
+ cc = si_setcoreidx(sih, SI_CC_IDX);
+ sromctrl = R_REG(sii->osh, &cc->sromcontrol);
+ si_setcoreidx(sih, origidx);
+ return (sromctrl & SRC_PRESENT);
+ }
+
+ switch (CHIPID(sih->chip)) {
+ case BCM4312_CHIP_ID:
+ return ((sih->chipst & CST4312_SPROM_OTP_SEL_MASK) != CST4312_OTP_SEL);
+ case BCM4325_CHIP_ID:
+ return (sih->chipst & CST4325_SPROM_SEL) != 0;
+ case BCM4322_CHIP_ID:
+ case BCM43221_CHIP_ID:
+ case BCM43231_CHIP_ID:
+ case BCM43222_CHIP_ID:
+ case BCM43111_CHIP_ID:
+ case BCM43112_CHIP_ID:
+ case BCM4342_CHIP_ID:
+ {
+ uint32 spromotp;
+ spromotp = (sih->chipst & CST4322_SPROM_OTP_SEL_MASK) >>
+ CST4322_SPROM_OTP_SEL_SHIFT;
+ return (spromotp & CST4322_SPROM_PRESENT) != 0;
+ }
+ case BCM4329_CHIP_ID:
+ return (sih->chipst & CST4329_SPROM_SEL) != 0;
+ case BCM4315_CHIP_ID:
+ return (sih->chipst & CST4315_SPROM_SEL) != 0;
+ case BCM4319_CHIP_ID:
+ return (sih->chipst & CST4319_SPROM_SEL) != 0;
+
+ case BCM4336_CHIP_ID:
+ case BCM43362_CHIP_ID:
+ return (sih->chipst & CST4336_SPROM_PRESENT) != 0;
+
+ case BCM4330_CHIP_ID:
+ return (sih->chipst & CST4330_SPROM_PRESENT) != 0;
+ case BCM4313_CHIP_ID:
+ return (sih->chipst & CST4313_SPROM_PRESENT) != 0;
+ case BCM43239_CHIP_ID:
+ return ((sih->chipst & CST43239_SPROM_MASK) &&
+ !(sih->chipst & CST43239_SFLASH_MASK));
+ default:
+ return TRUE;
+ }
+}
diff --git a/drivers/net/wireless/bcmdhd/wl_android.c b/drivers/net/wireless/bcmdhd/wl_android.c
index 9ca3d60..2cbe333 100644
--- a/drivers/net/wireless/bcmdhd/wl_android.c
+++ b/drivers/net/wireless/bcmdhd/wl_android.c
@@ -2,13 +2,13 @@
* Linux cfg80211 driver - Android related functions
*
* Copyright (C) 1999-2011, Broadcom Corporation
- *
+ *
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
* under the terms of the GNU General Public License version 2 (the "GPL"),
* available at http://www.broadcom.com/licenses/GPLv2.php, with the
* following added to such license:
- *
+ *
* As a special exception, the copyright holders of this software give you
* permission to link this software with independent modules, and to copy and
* distribute the resulting executable under terms of your choice, provided that
@@ -16,7 +16,7 @@
* the license of that module. An independent module is a module which is not
* derived from this software. The special exception does not apply to any
* modifications of the software.
- *
+ *
* Notwithstanding the above, under no circumstances may you combine this
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
@@ -73,7 +73,6 @@
#define CMD_GETBAND "GETBAND"
#define CMD_COUNTRY "COUNTRY"
#define CMD_P2P_SET_NOA "P2P_SET_NOA"
-#define CMD_P2P_GET_NOA "P2P_GET_NOA"
#define CMD_P2P_SET_PS "P2P_SET_PS"
#define CMD_SET_AP_WPS_P2P_IE "SET_AP_WPS_P2P_IE"
@@ -537,9 +536,6 @@
bytes_written = wl_cfg80211_set_p2p_noa(net, command + skip,
priv_cmd.total_len - skip);
}
- else if (strnicmp(command, CMD_P2P_GET_NOA, strlen(CMD_P2P_GET_NOA)) == 0) {
- bytes_written = wl_cfg80211_get_p2p_noa(net, command, priv_cmd.total_len);
- }
else if (strnicmp(command, CMD_P2P_SET_PS, strlen(CMD_P2P_SET_PS)) == 0) {
int skip = strlen(CMD_P2P_SET_PS) + 1;
bytes_written = wl_cfg80211_set_p2p_ps(net, command + skip,
@@ -559,8 +555,10 @@
bytes_written = strlen("OK");
}
- if (bytes_written > 0) {
- if (bytes_written > priv_cmd.total_len) {
+ if (bytes_written >= 0) {
+ if ((bytes_written == 0) && (priv_cmd.total_len > 0))
+ command[0] = '\0';
+ if (bytes_written >= priv_cmd.total_len) {
DHD_ERROR(("%s: bytes_written = %d\n", __FUNCTION__, bytes_written));
bytes_written = priv_cmd.total_len;
} else {
@@ -571,7 +569,8 @@
DHD_ERROR(("%s: failed to copy data to user buffer\n", __FUNCTION__));
ret = -EFAULT;
}
- } else {
+ }
+ else {
ret = bytes_written;
}
@@ -608,30 +607,14 @@
return ret;
}
-int wl_android_post_init(void)
+void wl_android_post_init(void)
{
- struct net_device *ndev;
- int ret = 0;
- char buf[IFNAMSIZ];
if (!dhd_download_fw_on_driverload) {
/* Call customer gpio to turn off power with WL_REG_ON signal */
dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF);
g_wifi_on = 0;
- } else {
- memset(buf, 0, IFNAMSIZ);
-#ifdef CUSTOMER_HW2
- snprintf(buf, IFNAMSIZ, "%s%d", iface_name, 0);
-#else
- snprintf(buf, IFNAMSIZ, "%s%d", "eth", 0);
-#endif
- if ((ndev = dev_get_by_name (&init_net, buf)) != NULL) {
- dhd_dev_init_ioctl(ndev);
- dev_put(ndev);
- }
}
- return ret;
}
-
/**
* Functions for Android WiFi card detection
*/
@@ -675,20 +658,21 @@
}
}
-void* wl_android_prealloc(int section, unsigned long size)
+void *wl_android_prealloc(int section, unsigned long size)
{
void *alloc_ptr = NULL;
if (wifi_control_data && wifi_control_data->mem_prealloc) {
alloc_ptr = wifi_control_data->mem_prealloc(section, size);
if (alloc_ptr) {
DHD_INFO(("success alloc section %d\n", section));
- bzero(alloc_ptr, size);
+ if (size != 0L)
+ bzero(alloc_ptr, size);
return alloc_ptr;
}
}
DHD_ERROR(("can't alloc section %d\n", section));
- return 0;
+ return NULL;
}
int wifi_get_irq_number(unsigned long *irq_flags_ptr)
diff --git a/drivers/net/wireless/bcmdhd/wl_android.h b/drivers/net/wireless/bcmdhd/wl_android.h
index 17373b7..3983306 100644
--- a/drivers/net/wireless/bcmdhd/wl_android.h
+++ b/drivers/net/wireless/bcmdhd/wl_android.h
@@ -40,7 +40,7 @@
*/
int wl_android_init(void);
int wl_android_exit(void);
-int wl_android_post_init(void);
+void wl_android_post_init(void);
int wl_android_wifi_on(struct net_device *dev);
int wl_android_wifi_off(struct net_device *dev);
int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd);
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
index daa7d26..125888d 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
@@ -2,13 +2,13 @@
* Linux cfg80211 driver
*
* Copyright (C) 1999-2011, Broadcom Corporation
- *
+ *
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
* under the terms of the GNU General Public License version 2 (the "GPL"),
* available at http://www.broadcom.com/licenses/GPLv2.php, with the
* following added to such license:
- *
+ *
* As a special exception, the copyright holders of this software give you
* permission to link this software with independent modules, and to copy and
* distribute the resulting executable under terms of your choice, provided that
@@ -41,10 +41,9 @@
#include <dhd.h>
#include <dhdioctl.h>
#include <wlioctl.h>
+#include <dhd_cfg80211.h>
#include <proto/ethernet.h>
-#include <dngl_stats.h>
-#include <dhd.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/netdevice.h>
@@ -54,54 +53,33 @@
#include <linux/ieee80211.h>
#include <linux/wait.h>
#include <net/cfg80211.h>
-
#include <net/rtnetlink.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/firmware.h>
-#include <bcmsdbus.h>
#include <wlioctl.h>
#include <wldev_common.h>
#include <wl_cfg80211.h>
#include <wl_cfgp2p.h>
-static struct sdio_func *cfg80211_sdio_func;
-static struct wl_priv *wlcfg_drv_priv;
+static struct device *cfg80211_parent_dev = NULL;
+static int vsdb_supported = 0;
+struct wl_priv *wlcfg_drv_priv = NULL;
u32 wl_dbg_level = WL_DBG_ERR;
-#define WL_4329_FW_FILE "brcm/bcm4329-fullmac-4-218-248-5.bin"
-#define WL_4329_NVRAM_FILE "brcm/bcm4329-fullmac-4-218-248-5.txt"
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
#define MAX_WAIT_TIME 1500
-static s8 ioctlbuf[WLC_IOCTL_MAXLEN];
+#define WL_SCAN_ACTIVE_TIME 40
+#define WL_SCAN_PASSIVE_TIME 130
+#define DNGL_FUNC(func, parameters) func parameters;
#define COEX_DHCP
-#if defined(COEX_DHCP)
-#define BT_DHCP_eSCO_FIX /* use New SCO/eSCO smart YG
- * suppression
- */
-#define BT_DHCP_USE_FLAGS /* this flag boost wifi pkt priority
- * to max, caution: -not fair to sco
- */
-#define BT_DHCP_OPPR_WIN_TIME 2500 /* T1 start SCO/ESCo priority
- * suppression
- */
-#define BT_DHCP_FLAG_FORCE_TIME 5500 /* T2 turn off SCO/SCO supperesion
- * is (timeout)
- */
-enum wl_cfg80211_btcoex_status {
- BT_DHCP_IDLE,
- BT_DHCP_START,
- BT_DHCP_OPPR_WIN,
- BT_DHCP_FLAG_FORCE_TIMEOUT
-};
-static int wl_cfg80211_btcoex_init(struct wl_priv *wl);
-static void wl_cfg80211_btcoex_deinit(struct wl_priv *wl);
-#endif
+/* Set this to 1 to use a seperate interface (p2p0)
+ * for p2p operations.
+ */
+#define ENABLE_P2P_INTERFACE 1
/* This is to override regulatory domains defined in cfg80211 module (reg.c)
* By default world regulatory domain defined in reg.c puts the flags NL80211_RRF_PASSIVE_SCAN
@@ -224,7 +202,7 @@
struct cfg80211_pmksa *pmksa);
static s32 wl_cfg80211_flush_pmksa(struct wiphy *wiphy,
struct net_device *dev);
-static void wl_notify_escan_complete(struct wl_priv *wl, bool aborted);
+static void wl_notify_escan_complete(struct wl_priv *wl, struct net_device *ndev, bool aborted);
/*
* event & event Q handlers for cfg80211 interfaces
*/
@@ -242,6 +220,8 @@
const wl_event_msg_t *msg, void *data);
static void wl_put_event(struct wl_event_q *e);
static void wl_wakeup_event(struct wl_priv *wl);
+static s32 wl_notify_connect_status_ap(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e, void *data);
static s32 wl_notify_connect_status(struct wl_priv *wl,
struct net_device *ndev,
const wl_event_msg_t *e, void *data);
@@ -256,22 +236,12 @@
const wl_event_msg_t *e, void *data);
static s32 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
const wl_event_msg_t *e, void *data);
+static s32 wl_notify_pfn_status(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e, void *data);
/*
- * register/deregister sdio function
+ * register/deregister parent device
*/
-struct sdio_func *wl_cfg80211_get_sdio_func(void);
-static void wl_clear_sdio_func(void);
-
-/*
- * ioctl utilites
- */
-static s32 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
- s32 buf_len);
-static __used s32 wl_dev_bufvar_set(struct net_device *dev, s8 *name,
- s8 *buf, s32 len);
-static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val);
-static s32 wl_dev_intvar_get(struct net_device *dev, s8 *name,
- s32 *retval);
+static void wl_cfg80211_clear_parent_dev(void);
/*
* cfg80211 set_wiphy_params utilities
@@ -283,10 +253,10 @@
/*
* wl profile utilities
*/
-static s32 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e,
- void *data, s32 item);
-static void *wl_read_prof(struct wl_priv *wl, s32 item);
-static void wl_init_prof(struct wl_priv *wl);
+static s32 wl_update_prof(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e, void *data, s32 item);
+static void *wl_read_prof(struct wl_priv *wl, struct net_device *ndev, s32 item);
+static void wl_init_prof(struct wl_priv *wl, struct net_device *ndev);
/*
* cfg80211 connect utilites
@@ -314,14 +284,14 @@
static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size);
static u32 wl_get_ielen(struct wl_priv *wl);
-static s32 wl_mode_to_nl80211_iftype(s32 mode);
-static struct wireless_dev *wl_alloc_wdev(struct device *sdiofunc_dev);
+static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *dev);
static void wl_free_wdev(struct wl_priv *wl);
static s32 wl_inform_bss(struct wl_priv *wl);
static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi);
static s32 wl_update_bss_info(struct wl_priv *wl, struct net_device *ndev);
+static chanspec_t wl_cfg80211_get_shared_freq(struct wiphy *wiphy);
static s32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
u8 key_idx, const u8 *mac_addr,
@@ -347,42 +317,19 @@
static __used bool wl_is_ibssstarter(struct wl_priv *wl);
/*
- * dongle up/down , default configuration utilities
+ * link up/down , default configuration utilities
*/
+static s32 __wl_cfg80211_up(struct wl_priv *wl);
+static s32 __wl_cfg80211_down(struct wl_priv *wl);
+static s32 wl_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add);
static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e);
static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e, struct net_device *ndev);
static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e);
static void wl_link_up(struct wl_priv *wl);
static void wl_link_down(struct wl_priv *wl);
-static s32 wl_dongle_mode(struct wl_priv *wl, struct net_device *ndev, s32 iftype);
-static s32 __wl_cfg80211_up(struct wl_priv *wl);
-static s32 __wl_cfg80211_down(struct wl_priv *wl);
-static s32 wl_dongle_probecap(struct wl_priv *wl);
+static s32 wl_config_ifmode(struct wl_priv *wl, struct net_device *ndev, s32 iftype);
static void wl_init_conf(struct wl_conf *conf);
-static s32 wl_dongle_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add);
-
-/*
- * dongle configuration utilities
- */
-#ifndef EMBEDDED_PLATFORM
-static s32 wl_dongle_country(struct net_device *ndev, u8 ccode);
-static s32 wl_dongle_up(struct net_device *ndev, u32 up);
-static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode);
-static s32 wl_dongle_glom(struct net_device *ndev, u32 glom,
- u32 dongle_align);
-static s32 wl_dongle_roam(struct net_device *ndev, u32 roamvar,
- u32 bcn_timeout);
-static s32 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
- s32 scan_unassoc_time);
-static s32 wl_dongle_offload(struct net_device *ndev, s32 arpoe,
- s32 arp_ol);
-static s32 wl_pattern_atoh(s8 *src, s8 *dst);
-static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode);
static s32 wl_update_wiphybands(struct wl_priv *wl);
-#endif /* !EMBEDDED_PLATFORM */
-static __used void wl_dongle_poweron(struct wl_priv *wl);
-static __used void wl_dongle_poweroff(struct wl_priv *wl);
-static s32 wl_config_dongle(struct wl_priv *wl, bool need_lock);
/*
* iscan handler
@@ -406,33 +353,20 @@
static s32 wl_iscan_aborted(struct wl_priv *wl);
/*
- * fw/nvram downloading handler
- */
-static void wl_init_fw(struct wl_fw_ctrl *fw);
-
-/*
* find most significant bit set
*/
static __used u32 wl_find_msb(u16 bit16);
/*
- * update pmklist to dongle
- */
-static __used s32 wl_update_pmklist(struct net_device *dev,
- struct wl_pmk_list *pmk_list, s32 err);
-
-/*
- * debufs support
- */
-static int wl_debugfs_add_netdev_params(struct wl_priv *wl);
-static void wl_debugfs_remove_netdev(struct wl_priv *wl);
-
-/*
* rfkill support
*/
static int wl_setup_rfkill(struct wl_priv *wl, bool setup);
static int wl_rfkill_set(void *data, bool blocked);
+static wl_scan_params_t *wl_cfg80211_scan_alloc_params(int channel,
+ int nprobes, int *out_params_size);
+static void get_primary_mac(struct wl_priv *wl, struct ether_addr *mac);
+
/*
* Some external functions, TODO: move them to dhd_linux.h
*/
@@ -444,10 +378,10 @@
#define CHECK_SYS_UP(wlpriv) \
do { \
- if (unlikely(!wl_get_drv_status(wlpriv, READY))) { \
- WL_INFO(("device is not ready : status (%d)\n", \
- (int)wlpriv->status)); \
- return -EIO; \
+ struct net_device *ndev = wl_to_prmry_ndev(wlpriv); \
+ if (unlikely(!wl_get_drv_status(wlpriv, READY, ndev))) { \
+ WL_INFO(("device is not ready\n")); \
+ return -EIO; \
} \
} while (0)
@@ -573,7 +507,22 @@
.channels = __wl_2ghz_channels,
.n_channels = ARRAY_SIZE(__wl_2ghz_channels),
.bitrates = wl_g_rates,
- .n_bitrates = wl_g_rates_size
+ .n_bitrates = wl_g_rates_size,
+#if ENABLE_P2P_INTERFACE
+ /* wpa_supplicant sets wmm_enabled based on whether ht_cap
+ * is present or not. The wmm_enabled is inturn used to
+ * set the replay counters in the RSN IE. Without this
+ * the 4way handshake will fail complaining that IE in beacon
+ * doesn't match with the IE present in the 3/4 EAPOL msg.
+ */
+ .ht_cap = {
+ IEEE80211_HT_CAP_SGI_20 |
+ IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU,
+ .ht_supported = TRUE,
+ .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
+ .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16
+ }
+#endif
};
static struct ieee80211_supported_band __wl_band_5ghz_a = {
@@ -740,6 +689,43 @@
}
}
+static chanspec_t wl_cfg80211_get_shared_freq(struct wiphy *wiphy)
+{
+ if (vsdb_supported) {
+ return wf_chspec_aton(WL_P2P_TEMP_CHAN);
+ }
+ else {
+ chanspec_t chspec;
+ int err = 0;
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ struct net_device *dev = wl_to_prmry_ndev(wl);
+ struct ether_addr bssid;
+ struct wl_bss_info *bss = NULL;
+ if ((err = wldev_ioctl(dev, WLC_GET_BSSID, &bssid, sizeof(bssid), false))) {
+ /* STA interface is not associated. So start the new interface on a temp
+ * channel . Later proper channel will be applied by the above framework
+ * via set_channel (cfg80211 API).
+ */
+ WL_DBG(("Not associated. Return a temp channel. \n"));
+ return wf_chspec_aton(WL_P2P_TEMP_CHAN);
+ }
+
+
+ *(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX);
+ if ((err = wldev_ioctl(dev, WLC_GET_BSS_INFO, wl->extra_buf,
+ sizeof(WL_EXTRA_BUF_MAX), false))) {
+ WL_ERR(("Failed to get associated bss info, use temp channel \n"));
+ chspec = wf_chspec_aton(WL_P2P_TEMP_CHAN);
+ }
+ else {
+ bss = (struct wl_bss_info *) (wl->extra_buf + 4);
+ chspec = bss->chanspec;
+ WL_DBG(("Valid BSS Found. chanspec:%d \n", bss->chanspec));
+ }
+ return chspec;
+ }
+}
+
static struct net_device* wl_cfg80211_add_monitor_if(char *name)
{
int ret = 0;
@@ -758,15 +744,17 @@
s32 err;
s32 timeout = -1;
s32 wlif_type = -1;
- s32 index = 0;
s32 mode = 0;
chanspec_t chspec;
struct wl_priv *wl = wiphy_priv(wiphy);
struct net_device *_ndev;
- dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
- int (*net_attach)(dhd_pub_t *dhdp, int ifidx);
+ struct ether_addr primary_mac;
+ int (*net_attach)(void *dhdp, int ifidx);
bool rollback_lock = false;
+ /* Use primary I/F for sending cmds down to firmware */
+ _ndev = wl_to_prmry_ndev(wl);
+
WL_DBG(("if name: %s, type: %d\n", name, type));
switch (type) {
case NL80211_IFTYPE_ADHOC:
@@ -798,6 +786,8 @@
WL_ERR(("name is NULL\n"));
return NULL;
}
+ if (wl->iface_cnt == IFACE_MAX_CNT)
+ return ERR_PTR(-ENOMEM);
if (wl->p2p_supported && (wlif_type != -1)) {
if (wl_get_p2p_status(wl, IF_DELETING)) {
/* wait till IF_DEL is complete
@@ -809,7 +799,7 @@
}
WL_INFO(("%s: Released the lock and wait till IF_DEL is complete\n",
__func__));
- timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
+ timeout = wait_event_interruptible_timeout(wl->netif_change_event,
(wl_get_p2p_status(wl, IF_DELETING) == false),
msecs_to_jiffies(MAX_WAIT_TIME));
@@ -826,17 +816,24 @@
return ERR_PTR(-EAGAIN);
}
}
- if (!p2p_on(wl) && strstr(name, WL_P2P_INTERFACE_PREFIX)) {
+ if (!p2p_is_on(wl) && strstr(name, WL_P2P_INTERFACE_PREFIX)) {
p2p_on(wl) = true;
wl_cfgp2p_set_firm_p2p(wl);
wl_cfgp2p_init_discovery(wl);
+ get_primary_mac(wl, &primary_mac);
+ wl_cfgp2p_generate_bss_mac(&primary_mac,
+ &wl->p2p->dev_addr, &wl->p2p->int_addr);
}
+
memset(wl->p2p->vir_ifname, 0, IFNAMSIZ);
strncpy(wl->p2p->vir_ifname, name, IFNAMSIZ - 1);
- wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p->dev_addr, &wl->p2p->int_addr);
- /* Temporary use channel 11, in case GO will be changed with set_channel API */
- chspec = wf_chspec_aton(WL_P2P_TEMP_CHAN);
+
+ /* In concurrency case, STA may be already associated in a particular channel.
+ * so retrieve the current channel of primary interface and then start the virtual
+ * interface on that.
+ */
+ chspec = wl_cfg80211_get_shared_freq(wiphy);
/* For P2P mode, use P2P-specific driver features to create the
* bss: "wl p2p_ifadd"
@@ -844,10 +841,12 @@
wl_set_p2p_status(wl, IF_ADD);
err = wl_cfgp2p_ifadd(wl, &wl->p2p->int_addr, htod32(wlif_type), chspec);
- if (unlikely(err))
+ if (unlikely(err)) {
+ WL_ERR((" virtual iface add failed (%d) \n", err));
return ERR_PTR(-ENOMEM);
+ }
- timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
+ timeout = wait_event_interruptible_timeout(wl->netif_change_event,
(wl_get_p2p_status(wl, IF_ADD) == false),
msecs_to_jiffies(MAX_WAIT_TIME));
if (timeout > 0 && (!wl_get_p2p_status(wl, IF_ADD))) {
@@ -860,25 +859,22 @@
}
vwdev->wiphy = wl->wdev->wiphy;
WL_INFO((" virtual interface(%s) is created memalloc done \n",
- wl->p2p->vir_ifname));
- index = alloc_idx_vwdev(wl);
- wl->vwdev[index] = vwdev;
- vwdev->iftype =
- (wlif_type == WL_P2P_IF_CLIENT) ? NL80211_IFTYPE_STATION
- : NL80211_IFTYPE_AP;
+ wl->p2p->vir_ifname));
+ vwdev->iftype = type;
_ndev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION);
_ndev->ieee80211_ptr = vwdev;
SET_NETDEV_DEV(_ndev, wiphy_dev(vwdev->wiphy));
vwdev->netdev = _ndev;
- wl_set_drv_status(wl, READY);
+ wl_set_drv_status(wl, READY, _ndev);
wl->p2p->vif_created = true;
- set_mode_by_netdev(wl, _ndev, mode);
+ wl_set_mode_by_netdev(wl, _ndev, mode);
net_attach = wl_to_p2p_bss_private(wl, P2PAPI_BSSCFG_CONNECTION);
if (rtnl_is_locked()) {
rtnl_unlock();
rollback_lock = true;
}
- if (net_attach && !net_attach(dhd, _ndev->ifindex)) {
+ if (net_attach && !net_attach(wl->pub, _ndev->ifindex)) {
+ wl_alloc_netinfo(wl, _ndev, vwdev, mode);
WL_DBG((" virtual interface(%s) is "
"created net attach done\n", wl->p2p->vir_ifname));
} else {
@@ -911,30 +907,39 @@
s32 timeout = -1;
s32 ret = 0;
WL_DBG(("Enter\n"));
+
+ if (wl->p2p_net == dev) {
+ /* Since there is no ifidx corresponding to p2p0, cmds to
+ * firmware should be routed through primary I/F
+ */
+ dev = wl_to_prmry_ndev(wl);
+ }
+
if (wl->p2p_supported) {
memcpy(p2p_mac.octet, wl->p2p->int_addr.octet, ETHER_ADDR_LEN);
if (wl->p2p->vif_created) {
- if (wl_get_drv_status(wl, SCANNING)) {
+ if (wl_get_drv_status(wl, SCANNING, dev)) {
wl_cfg80211_scan_abort(wl, dev);
}
wldev_iovar_setint(dev, "mpc", 1);
wl_set_p2p_status(wl, IF_DELETING);
ret = wl_cfgp2p_ifdel(wl, &p2p_mac);
- if (ret) {
/* Firmware could not delete the interface so we will not get WLC_E_IF
* event for cleaning the dhd virtual nw interace
* So lets do it here. Failures from fw will ensure the application to do
* ifconfig <inter> down and up sequnce, which will reload the fw
* however we should cleanup the linux network virtual interfaces
*/
- dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
- WL_ERR(("Firmware returned an error from p2p_ifdel\n"));
- WL_ERR(("try to remove linux virtual interface %s\n", dev->name));
- dhd_del_if(dhd->info, dhd_net2idx(dhd->info, dev));
+ /* Request framework to RESET and clean up */
+ if (ret) {
+ struct net_device *ndev = wl_to_prmry_ndev(wl);
+ WL_ERR(("Firmware returned an error (%d) from p2p_ifdel"
+ "HANG Notification sent to %s\n", ret, ndev->name));
+ wl_cfg80211_hang(ndev, WLAN_REASON_UNSPECIFIED);
}
/* Wait for any pending scan req to get aborted from the sysioc context */
- timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
+ timeout = wait_event_interruptible_timeout(wl->netif_change_event,
(wl_get_p2p_status(wl, IF_DELETING) == false),
msecs_to_jiffies(MAX_WAIT_TIME));
if (timeout > 0 && !wl_get_p2p_status(wl, IF_DELETING)) {
@@ -961,6 +966,7 @@
s32 mode = 0;
chanspec_t chspec;
struct wl_priv *wl = wiphy_priv(wiphy);
+
WL_DBG(("Enter \n"));
switch (type) {
case NL80211_IFTYPE_MONITOR:
@@ -988,28 +994,33 @@
return -EINVAL;
}
-
if (ap) {
- set_mode_by_netdev(wl, ndev, mode);
+ wl_set_mode_by_netdev(wl, ndev, mode);
if (wl->p2p_supported && wl->p2p->vif_created) {
WL_DBG(("p2p_vif_created (%d) p2p_on (%d)\n", wl->p2p->vif_created,
p2p_on(wl)));
- chspec = wf_chspec_aton(WL_P2P_TEMP_CHAN);
+ wldev_iovar_setint(ndev, "mpc", 0);
+ /* In concurrency case, STA may be already associated in a particular
+ * channel. so retrieve the current channel of primary interface and
+ * then start the virtual interface on that.
+ */
+ chspec = wl_cfg80211_get_shared_freq(wiphy);
+
wlif_type = ap ? WL_P2P_IF_GO : WL_P2P_IF_CLIENT;
WL_ERR(("%s : ap (%d), infra (%d), iftype: (%d)\n",
ndev->name, ap, infra, type));
wl_set_p2p_status(wl, IF_CHANGING);
wl_clr_p2p_status(wl, IF_CHANGED);
err = wl_cfgp2p_ifchange(wl, &wl->p2p->int_addr, htod32(wlif_type), chspec);
- timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
+ timeout = wait_event_interruptible_timeout(wl->netif_change_event,
(wl_get_p2p_status(wl, IF_CHANGED) == true),
msecs_to_jiffies(MAX_WAIT_TIME));
- set_mode_by_netdev(wl, ndev, mode);
+ wl_set_mode_by_netdev(wl, ndev, mode);
wl_clr_p2p_status(wl, IF_CHANGING);
wl_clr_p2p_status(wl, IF_CHANGED);
} else if (ndev == wl_to_prmry_ndev(wl) &&
- !wl_get_drv_status(wl, AP_CREATED)) {
- wl_set_drv_status(wl, AP_CREATING);
+ !wl_get_drv_status(wl, AP_CREATED, ndev)) {
+ wl_set_drv_status(wl, AP_CREATING, ndev);
if (!wl->ap_info &&
!(wl->ap_info = kzalloc(sizeof(struct ap_info), GFP_KERNEL))) {
WL_ERR(("struct ap_saved_ie allocation failed\n"));
@@ -1027,15 +1038,16 @@
s32
wl_cfg80211_notify_ifadd(struct net_device *ndev, s32 idx, s32 bssidx,
-int (*_net_attach)(dhd_pub_t *dhdp, int ifidx))
+ void* _net_attach)
{
struct wl_priv *wl = wlcfg_drv_priv;
s32 ret = BCME_OK;
+ WL_DBG(("Enter"));
if (!ndev) {
WL_ERR(("net is NULL\n"));
return 0;
}
- if (wl->p2p_supported) {
+ if (wl->p2p_supported && wl_get_p2p_status(wl, IF_ADD)) {
WL_DBG(("IF_ADD event called from dongle, old interface name: %s,"
"new name: %s\n", ndev->name, wl->p2p->vir_ifname));
/* Assign the net device to CONNECT BSSCFG */
@@ -1046,7 +1058,9 @@
ndev->ifindex = idx;
wl_clr_p2p_status(wl, IF_ADD);
- wake_up_interruptible(&wl->dongle_event_wait);
+ wake_up_interruptible(&wl->netif_change_event);
+ } else {
+ ret = BCME_NOTREADY;
}
return ret;
}
@@ -1063,8 +1077,10 @@
return 0;
}
- if (p2p_is_on(wl) && wl->p2p->vif_created) {
- if (wl->scan_request) {
+ if (p2p_is_on(wl) && wl->p2p->vif_created &&
+ wl_get_p2p_status(wl, IF_DELETING)) {
+ if (wl->scan_request &&
+ (wl->escan_info.ndev == ndev)) {
/* Abort any pending scan requests */
wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
if (!rtnl_is_locked()) {
@@ -1072,7 +1088,7 @@
rollback_lock = true;
}
WL_DBG(("ESCAN COMPLETED\n"));
- wl_notify_escan_complete(wl, true);
+ wl_notify_escan_complete(wl, ndev, true);
if (rollback_lock)
rtnl_unlock();
}
@@ -1091,7 +1107,7 @@
}
/* Wake up any waiting thread */
- wake_up_interruptible(&wl->dongle_event_wait);
+ wake_up_interruptible(&wl->netif_change_event);
return 0;
}
@@ -1123,15 +1139,15 @@
struct wl_priv *wl = wlcfg_drv_priv;
if (wl_get_p2p_status(wl, IF_CHANGING)) {
wl_set_p2p_status(wl, IF_CHANGED);
- wake_up_interruptible(&wl->dongle_event_wait);
+ wake_up_interruptible(&wl->netif_change_event);
}
return 0;
}
static void wl_scan_prep(struct wl_scan_params *params, struct cfg80211_scan_request *request)
{
- u32 n_ssids = request->n_ssids;
- u32 n_channels = request->n_channels;
+ u32 n_ssids;
+ u32 n_channels;
u16 channel;
chanspec_t chanspec;
s32 i, offset;
@@ -1160,6 +1176,13 @@
params->passive_time = htod32(params->passive_time);
params->home_time = htod32(params->home_time);
+ /* if request is null just exit so it will be all channel broadcast scan */
+ if (!request)
+ return;
+
+ n_ssids = request->n_ssids;
+ n_channels = request->n_channels;
+
/* Copy channel array if applicable */
WL_SCAN(("### List of channelspecs to scan ###\n"));
if (n_channels > 0) {
@@ -1248,8 +1271,7 @@
return -ENOMEM;
}
- if (request != NULL)
- wl_scan_prep(¶ms->params, request);
+ wl_scan_prep(¶ms->params, request);
params->version = htod32(ISCAN_REQ_VERSION);
params->action = htod16(action);
@@ -1261,7 +1283,7 @@
goto done;
}
err = wldev_iovar_setbuf(iscan->dev, "iscan", params, params_size,
- iscan->ioctl_buf, WLC_IOCTL_MEDLEN);
+ iscan->ioctl_buf, WLC_IOCTL_MEDLEN, NULL);
if (unlikely(err)) {
if (err == -EBUSY) {
WL_ERR(("system busy : iscan canceled\n"));
@@ -1299,6 +1321,25 @@
}
static s32
+wl_get_valid_channels(struct net_device *ndev, u8 *valid_chan_list, s32 size)
+{
+ wl_uint32_list_t *list;
+ s32 err = BCME_OK;
+ if (valid_chan_list == NULL || size <= 0)
+ return -ENOMEM;
+
+ memset(valid_chan_list, 0, size);
+ list = (wl_uint32_list_t *)(void *) valid_chan_list;
+ list->count = htod32(WL_NUMCHANNELS);
+ err = wldev_ioctl(ndev, WLC_GET_VALID_CHANNELS, valid_chan_list, size, false);
+ if (err != 0) {
+ WL_ERR(("get channels failed with %d\n", err));
+ }
+
+ return err;
+}
+
+static s32
wl_run_escan(struct wl_priv *wl, struct net_device *ndev,
struct cfg80211_scan_request *request, uint16 action)
{
@@ -1306,12 +1347,16 @@
u32 n_channels;
u32 n_ssids;
s32 params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_escan_params_t, params));
- wl_escan_params_t *params;
+ wl_escan_params_t *params = NULL;
struct cfg80211_scan_request *scan_request = wl->scan_request;
+ u8 chan_buf[sizeof(u32)*(WL_NUMCHANNELS + 1)];
u32 num_chans = 0;
+ s32 channel;
+ s32 n_valid_chan;
s32 search_state = WL_P2P_DISC_ST_SCAN;
- u32 i;
+ u32 i, j, n_nodfs = 0;
u16 *default_chan_list = NULL;
+ wl_uint32_list_t *list;
struct net_device *dev = NULL;
WL_DBG(("Enter \n"));
@@ -1340,8 +1385,7 @@
goto exit;
}
- if (request != NULL)
- wl_scan_prep(¶ms->params, request);
+ wl_scan_prep(¶ms->params, request);
params->version = htod32(ESCAN_REQ_VERSION);
params->action = htod16(action);
params->sync_id = htod16(0x1234);
@@ -1352,13 +1396,15 @@
goto exit;
}
err = wldev_iovar_setbuf(ndev, "escan", params, params_size,
- wl->escan_ioctl_buf, WLC_IOCTL_MEDLEN);
+ wl->escan_ioctl_buf, WLC_IOCTL_MEDLEN, NULL);
if (unlikely(err))
WL_ERR((" Escan set error (%d)\n", err));
kfree(params);
}
- else if (p2p_on(wl) && p2p_scan(wl)) {
+ else if (p2p_is_on(wl) && p2p_scan(wl)) {
/* P2P SCAN TRIGGER */
+ s32 _freq = 0;
+ n_nodfs = 0;
if (scan_request && scan_request->n_channels) {
num_chans = scan_request->n_channels;
WL_SCAN((" chann number : %d\n", num_chans));
@@ -1369,11 +1415,26 @@
err = -ENOMEM;
goto exit;
}
- for (i = 0; i < num_chans; i++)
- {
- default_chan_list[i] =
- ieee80211_frequency_to_channel(
- scan_request->channels[i]->center_freq);
+ if (!wl_get_valid_channels(ndev, chan_buf, sizeof(chan_buf))) {
+ list = (wl_uint32_list_t *) chan_buf;
+ n_valid_chan = dtoh32(list->count);
+ for (i = 0; i < num_chans; i++)
+ {
+ _freq = scan_request->channels[i]->center_freq;
+ channel = ieee80211_frequency_to_channel(_freq);
+ /* remove DFS channels */
+ if (channel < 52 || channel > 140) {
+ for (j = 0; j < n_valid_chan; j++) {
+ /* allows only supported channel on
+ * current reguatory
+ */
+ if (channel == (dtoh32(list->element[j])))
+ default_chan_list[n_nodfs++] =
+ channel;
+ }
+ }
+
+ }
}
if (num_chans == 3 && (
(default_chan_list[0] == SOCIAL_CHAN_1) &&
@@ -1383,12 +1444,15 @@
search_state = WL_P2P_DISC_ST_SEARCH;
WL_INFO(("P2P SEARCH PHASE START \n"));
} else if ((dev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION)) &&
- (get_mode_by_netdev(wl, dev) == WL_MODE_AP)) {
+ (wl_get_mode_by_netdev(wl, dev) == WL_MODE_AP)) {
/* If you are already a GO, then do SEARCH only */
WL_INFO(("Already a GO. Do SEARCH Only"));
search_state = WL_P2P_DISC_ST_SEARCH;
+ num_chans = n_nodfs;
+
} else {
WL_INFO(("P2P SCAN STATE START \n"));
+ num_chans = n_nodfs;
}
}
@@ -1413,7 +1477,7 @@
s32 passive_scan;
wl_scan_results_t *results;
WL_SCAN(("Enter \n"));
-
+ wl->escan_info.ndev = ndev;
wl->escan_info.wiphy = wiphy;
wl->escan_info.escan_state = WL_ESCAN_STATE_SCANING;
passive_scan = wl->active_scan ? 0 : 1;
@@ -1440,36 +1504,41 @@
struct wl_priv *wl = wiphy_priv(wiphy);
struct cfg80211_ssid *ssids;
struct wl_scan_req *sr = wl_to_sr(wl);
+ struct ether_addr primary_mac;
wpa_ie_fixed_t *wps_ie;
s32 passive_scan;
bool iscan_req;
bool escan_req;
- bool spec_scan;
bool p2p_ssid;
s32 err = 0;
s32 i;
u32 wpsie_len = 0;
u8 wpsie[IE_MAX_LEN];
+ /* If scan req comes for p2p0, send it over primary I/F
+ * Scan results will be delivered corresponding to cfg80211_scan_request
+ */
+ if (ndev == wl->p2p_net) {
+ ndev = wl_to_prmry_ndev(wl);
+ }
+
WL_DBG(("Enter wiphy (%p)\n", wiphy));
- if (unlikely(wl_get_drv_status(wl, SCANNING))) {
- WL_ERR(("Scanning already : status (%d)\n", (int)wl->status));
+ if (wl_get_drv_status_all(wl, SCANNING)) {
+ WL_ERR(("Scanning already\n"));
return -EAGAIN;
}
- if (unlikely(wl_get_drv_status(wl, SCAN_ABORTING))) {
- WL_ERR(("Scanning being aborted : status (%d)\n",
- (int)wl->status));
+ if (wl_get_drv_status(wl, SCAN_ABORTING, ndev)) {
+ WL_ERR(("Scanning being aborted\n"));
return -EAGAIN;
}
- if (request->n_ssids > WL_SCAN_PARAMS_SSID_MAX) {
- WL_ERR(("n_ssids > WL_SCAN_PARAMS_SSID_MAX\n"));
+ if (request && request->n_ssids > WL_SCAN_PARAMS_SSID_MAX) {
+ WL_ERR(("request null or n_ssids > WL_SCAN_PARAMS_SSID_MAX\n"));
return -EOPNOTSUPP;
}
/* Arm scan timeout timer */
mod_timer(&wl->scan_timeout, jiffies + WL_SCAN_TIMER_INTERVAL_MS * HZ / 1000);
iscan_req = false;
- spec_scan = false;
if (request) { /* scan bss */
ssids = request->ssids;
if (wl->iscan_on && (!ssids || !ssids->ssid_len || request->n_ssids != 1)) {
@@ -1490,6 +1559,9 @@
/* p2p on at the first time */
p2p_on(wl) = true;
wl_cfgp2p_set_firm_p2p(wl);
+ get_primary_mac(wl, &primary_mac);
+ wl_cfgp2p_generate_bss_mac(&primary_mac,
+ &wl->p2p->dev_addr, &wl->p2p->int_addr);
}
p2p_scan(wl) = true;
}
@@ -1543,7 +1615,7 @@
ssids = this_ssid;
}
wl->scan_request = request;
- wl_set_drv_status(wl, SCANNING);
+ wl_set_drv_status(wl, SCANNING, ndev);
if (iscan_req) {
err = wl_do_iscan(wl, request);
if (likely(!err))
@@ -1578,7 +1650,6 @@
sr->ssid.SSID_len = htod32(sr->ssid.SSID_len);
WL_SCAN(("Specific scan ssid=\"%s\" len=%d\n",
sr->ssid.SSID, sr->ssid.SSID_len));
- spec_scan = true;
} else {
WL_SCAN(("Broadcast scan\n"));
}
@@ -1606,7 +1677,7 @@
return 0;
scan_out:
- wl_clr_drv_status(wl, SCANNING);
+ wl_clr_drv_status(wl, SCANNING, ndev);
wl->scan_request = NULL;
return err;
}
@@ -1630,52 +1701,11 @@
return err;
}
-static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val)
-{
- s8 buf[WLC_IOCTL_SMLEN];
- u32 len;
- s32 err = 0;
-
- val = htod32(val);
- len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf));
- BUG_ON(unlikely(!len));
-
- err = wldev_ioctl(dev, WLC_SET_VAR, buf, len, false);
- if (unlikely(err)) {
- WL_ERR(("error (%d)\n", err));
- }
-
- return err;
-}
-
-static s32
-wl_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval)
-{
- union {
- s8 buf[WLC_IOCTL_SMLEN];
- s32 val;
- } var;
- u32 len;
- u32 data_null;
- s32 err = 0;
-
- len = bcm_mkiovar(name, (char *)(&data_null), 0,
- (char *)(&var), sizeof(var.buf));
- BUG_ON(unlikely(!len));
- err = wldev_ioctl(dev, WLC_GET_VAR, &var, len, false);
- if (unlikely(err)) {
- WL_ERR(("error (%d)\n", err));
- }
- *retval = dtoh32(var.val);
-
- return err;
-}
-
static s32 wl_set_rts(struct net_device *dev, u32 rts_threshold)
{
s32 err = 0;
- err = wl_dev_intvar_set(dev, "rtsthresh", rts_threshold);
+ err = wldev_iovar_setint(dev, "rtsthresh", rts_threshold);
if (unlikely(err)) {
WL_ERR(("Error (%d)\n", err));
return err;
@@ -1687,7 +1717,7 @@
{
s32 err = 0;
- err = wl_dev_intvar_set(dev, "fragthresh", frag_threshold);
+ err = wldev_iovar_setint_bsscfg(dev, "fragthresh", frag_threshold, 0);
if (unlikely(err)) {
WL_ERR(("Error (%d)\n", err));
return err;
@@ -1716,6 +1746,7 @@
s32 err = 0;
CHECK_SYS_UP(wl);
+ WL_DBG(("Enter\n"));
if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
(wl->conf->rts_threshold != wiphy->rts_threshold)) {
wl->conf->rts_threshold = wiphy->rts_threshold;
@@ -1745,7 +1776,6 @@
return err;
}
}
-
return err;
}
@@ -1862,7 +1892,7 @@
WL_ERR(("set wpa_auth failed (%d)\n", err));
return err;
}
- sec = wl_read_prof(wl, WL_PROF_SEC);
+ sec = wl_read_prof(wl, dev, WL_PROF_SEC);
sec->wpa_versions = sme->crypto.wpa_versions;
return err;
}
@@ -1901,7 +1931,7 @@
WL_ERR(("set auth failed (%d)\n", err));
return err;
}
- sec = wl_read_prof(wl, WL_PROF_SEC);
+ sec = wl_read_prof(wl, dev, WL_PROF_SEC);
sec->auth_type = sme->auth_type;
return err;
}
@@ -1973,7 +2003,7 @@
return err;
}
- sec = wl_read_prof(wl, WL_PROF_SEC);
+ sec = wl_read_prof(wl, dev, WL_PROF_SEC);
sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
sec->cipher_group = sme->crypto.cipher_group;
@@ -1990,7 +2020,7 @@
s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
if (sme->crypto.n_akm_suites) {
- err = wl_dev_intvar_get(dev, "wpa_auth", &val);
+ err = wldev_iovar_getint(dev, "wpa_auth", &val);
if (unlikely(err)) {
WL_ERR(("could not get wpa_auth (%d)\n", err));
return err;
@@ -2030,7 +2060,7 @@
return err;
}
}
- sec = wl_read_prof(wl, WL_PROF_SEC);
+ sec = wl_read_prof(wl, dev, WL_PROF_SEC);
sec->wpa_auth = sme->crypto.akm_suites[0];
return err;
@@ -2049,13 +2079,14 @@
WL_DBG(("key len (%d)\n", sme->key_len));
if (sme->key_len) {
- sec = wl_read_prof(wl, WL_PROF_SEC);
+ sec = wl_read_prof(wl, dev, WL_PROF_SEC);
WL_DBG(("wpa_versions 0x%x cipher_pairwise 0x%x\n",
sec->wpa_versions, sec->cipher_pairwise));
if (!(sec->wpa_versions & (NL80211_WPA_VERSION_1 |
NL80211_WPA_VERSION_2)) &&
(sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 |
- WLAN_CIPHER_SUITE_WEP104))) {
+ WLAN_CIPHER_SUITE_WEP104)))
+ {
memset(&key, 0, sizeof(key));
key.len = (u32) sme->key_len;
key.index = (u32) sme->key_idx;
@@ -2083,7 +2114,7 @@
WL_DBG(("key \"%s\"\n", key.data));
swap_key_from_BE(&key);
err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key),
- ioctlbuf, sizeof(ioctlbuf), bssidx);
+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
if (unlikely(err)) {
WL_ERR(("WLC_SET_KEY error (%d)\n", err));
return err;
@@ -2133,11 +2164,11 @@
}
/* Clean BSSID */
bzero(&bssid, sizeof(bssid));
- wl_update_prof(wl, NULL, (void *)&bssid, WL_PROF_BSSID);
+ wl_update_prof(wl, dev, NULL, (void *)&bssid, WL_PROF_BSSID);
if (IS_P2P_SSID(sme->ssid) && (dev != wl_to_prmry_ndev(wl))) {
/* we only allow to connect using virtual interface in case of P2P */
- if (p2p_on(wl) && is_wps_conn(sme)) {
+ if (p2p_is_on(wl) && is_wps_conn(sme)) {
WL_DBG(("ASSOC1 p2p index : %d sme->ie_len %d\n",
wl_cfgp2p_find_idx(wl, dev), sme->ie_len));
/* Have to apply WPS IE + P2P IE in assoc req frame */
@@ -2148,7 +2179,7 @@
P2PAPI_BSSCFG_DEVICE).p2p_probe_req_ie_len);
wl_cfgp2p_set_management_ie(wl, dev, wl_cfgp2p_find_idx(wl, dev),
VNDR_IE_ASSOCREQ_FLAG, sme->ie, sme->ie_len);
- } else if (p2p_on(wl) && (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
+ } else if (p2p_is_on(wl) && (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
/* This is the connect req after WPS is done [credentials exchanged]
* currently identified with WPA_VERSION_2 .
* Update the previously set IEs with
@@ -2177,10 +2208,10 @@
wpaie_len = (wpa_ie != NULL) ? wpa_ie->length : wpa2_ie->len;
wpaie_len += WPA_RSN_IE_TAG_FIXED_LEN;
wldev_iovar_setbuf(dev, "wpaie", wpaie, wpaie_len,
- ioctlbuf, sizeof(ioctlbuf));
+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
} else {
wldev_iovar_setbuf(dev, "wpaie", NULL, 0,
- ioctlbuf, sizeof(ioctlbuf));
+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
}
/* find the WPSIE */
@@ -2249,7 +2280,7 @@
ext_join_params = (wl_extjoin_params_t*)kzalloc(join_params_size, GFP_KERNEL);
if (ext_join_params == NULL) {
err = -ENOMEM;
- wl_clr_drv_status(wl, CONNECTING);
+ wl_clr_drv_status(wl, CONNECTING, dev);
goto exit;
}
ext_join_params->ssid.SSID_len = min(sizeof(ext_join_params->ssid.SSID), sme->ssid_len);
@@ -2258,12 +2289,13 @@
/* Set up join scan parameters */
ext_join_params->scan.scan_type = -1;
ext_join_params->scan.nprobes = 2;
- /* increate dwell time to receive probe response
- * from target AP at a noisy air
+ /* increate dwell time to receive probe response or detect Beacon
+ * from target AP at a noisy air only during connect command
*/
- ext_join_params->scan.active_time = 150;
- ext_join_params->scan.passive_time = 300;
+ ext_join_params->scan.active_time = WL_SCAN_ACTIVE_TIME*3;
+ ext_join_params->scan.passive_time = WL_SCAN_PASSIVE_TIME*3;
ext_join_params->scan.home_time = -1;
+
if (sme->bssid)
memcpy(&ext_join_params->assoc.bssid, sme->bssid, ETH_ALEN);
else
@@ -2288,12 +2320,12 @@
WL_INFO(("ssid \"%s\", len (%d)\n", ext_join_params->ssid.SSID,
ext_join_params->ssid.SSID_len));
}
- wl_set_drv_status(wl, CONNECTING);
- err = wldev_iovar_setbuf_bsscfg(dev, "join", ext_join_params, join_params_size, ioctlbuf,
- sizeof(ioctlbuf), wl_cfgp2p_find_idx(wl, dev));
+ wl_set_drv_status(wl, CONNECTING, dev);
+ err = wldev_iovar_setbuf_bsscfg(dev, "join", ext_join_params, join_params_size,
+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, wl_cfgp2p_find_idx(wl, dev), &wl->ioctl_buf_sync);
kfree(ext_join_params);
if (err) {
- wl_clr_drv_status(wl, CONNECTING);
+ wl_clr_drv_status(wl, CONNECTING, dev);
if (err == BCME_UNSUPPORTED) {
WL_DBG(("join iovar is not supported\n"));
goto set_ssid;
@@ -2309,7 +2341,7 @@
join_params.ssid.SSID_len = min(sizeof(join_params.ssid.SSID), sme->ssid_len);
memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len);
join_params.ssid.SSID_len = htod32(join_params.ssid.SSID_len);
- wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID);
+ wl_update_prof(wl, dev, NULL, &join_params.ssid, WL_PROF_SSID);
if (sme->bssid)
memcpy(&join_params.params.bssid, sme->bssid, ETH_ALEN);
else
@@ -2322,11 +2354,11 @@
WL_INFO(("ssid \"%s\", len (%d)\n", join_params.ssid.SSID,
join_params.ssid.SSID_len));
}
- wl_set_drv_status(wl, CONNECTING);
+ wl_set_drv_status(wl, CONNECTING, dev);
err = wldev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size, true);
if (err) {
WL_ERR(("error (%d)\n", err));
- wl_clr_drv_status(wl, CONNECTING);
+ wl_clr_drv_status(wl, CONNECTING, dev);
}
exit:
return err;
@@ -2343,23 +2375,23 @@
u8 *curbssid;
WL_ERR(("Reason %d\n", reason_code));
CHECK_SYS_UP(wl);
- act = *(bool *) wl_read_prof(wl, WL_PROF_ACT);
- curbssid = wl_read_prof(wl, WL_PROF_BSSID);
- if (likely(act)) {
+ act = *(bool *) wl_read_prof(wl, dev, WL_PROF_ACT);
+ curbssid = wl_read_prof(wl, dev, WL_PROF_BSSID);
+ if (act) {
/*
* Cancel ongoing scan to sync up with sme state machine of cfg80211.
*/
if (wl->scan_request) {
wl_cfg80211_scan_abort(wl, dev);
}
- wl_set_drv_status(wl, DISCONNECTING);
+ wl_set_drv_status(wl, DISCONNECTING, dev);
scbval.val = reason_code;
memcpy(&scbval.ea, curbssid, ETHER_ADDR_LEN);
scbval.val = htod32(scbval.val);
err = wldev_ioctl(dev, WLC_DISASSOC, &scbval,
sizeof(scb_val_t), true);
if (unlikely(err)) {
- wl_clr_drv_status(wl, DISCONNECTING);
+ wl_clr_drv_status(wl, DISCONNECTING, dev);
WL_ERR(("error (%d)\n", err));
return err;
}
@@ -2409,7 +2441,7 @@
txpwrmw = 0xffff;
else
txpwrmw = (u16) dbm;
- err = wl_dev_intvar_set(ndev, "qtxpower",
+ err = wldev_iovar_setint(ndev, "qtxpower",
(s32) (bcm_mw_to_qdbm(txpwrmw)));
if (unlikely(err)) {
WL_ERR(("qtxpower error (%d)\n", err));
@@ -2429,7 +2461,7 @@
s32 err = 0;
CHECK_SYS_UP(wl);
- err = wl_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
+ err = wldev_iovar_getint(ndev, "qtxpower", &txpwrdbm);
if (unlikely(err)) {
WL_ERR(("error (%d)\n", err));
return err;
@@ -2478,7 +2510,7 @@
struct wl_wsec_key key;
s32 err = 0;
s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
- s32 mode = get_mode_by_netdev(wl, dev);
+ s32 mode = wl_get_mode_by_netdev(wl, dev);
memset(&key, 0, sizeof(key));
key.index = (u32) key_idx;
@@ -2490,8 +2522,8 @@
if (key.len == 0) {
/* key delete */
swap_key_from_BE(&key);
- wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), ioctlbuf,
- sizeof(ioctlbuf), bssidx);
+ wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key),
+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
if (unlikely(err)) {
WL_ERR(("key delete error (%d)\n", err));
return err;
@@ -2549,11 +2581,11 @@
return -EINVAL;
}
swap_key_from_BE(&key);
-#ifdef CONFIG_WIRELESS_EXT
+#if defined(CONFIG_WIRELESS_EXT)
dhd_wait_pend8021x(dev);
#endif
- wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), ioctlbuf,
- sizeof(ioctlbuf), bssidx);
+ wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key),
+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
if (unlikely(err)) {
WL_ERR(("WLC_SET_KEY error (%d)\n", err));
return err;
@@ -2574,7 +2606,7 @@
u8 keybuf[8];
s32 bssidx = 0;
struct wl_priv *wl = wiphy_priv(wiphy);
- s32 mode = get_mode_by_netdev(wl, dev);
+ s32 mode = wl_get_mode_by_netdev(wl, dev);
WL_DBG(("key index (%d)\n", key_idx));
CHECK_SYS_UP(wl);
@@ -2635,8 +2667,8 @@
/* Set the new key/index */
swap_key_from_BE(&key);
- err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), ioctlbuf,
- sizeof(ioctlbuf), bssidx);
+ err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), wl->ioctl_buf,
+ WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
if (unlikely(err)) {
WL_ERR(("WLC_SET_KEY error (%d)\n", err));
return err;
@@ -2672,15 +2704,15 @@
CHECK_SYS_UP(wl);
memset(&key, 0, sizeof(key));
- key.index = (u32) key_idx;
key.flags = WL_PRIMARY_KEY;
key.algo = CRYPTO_ALGO_OFF;
+ key.index = (u32) key_idx;
WL_DBG(("key index (%d)\n", key_idx));
/* Set the new key/index */
swap_key_from_BE(&key);
- wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), ioctlbuf,
- sizeof(ioctlbuf), bssidx);
+ wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), wl->ioctl_buf,
+ WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
if (unlikely(err)) {
if (err == -EINVAL) {
if (key.index >= DOT11_MAX_DEFAULT_KEYS) {
@@ -2724,7 +2756,7 @@
}
switch (wsec & ~SES_OW_ENABLED) {
case WEP_ENABLED:
- sec = wl_read_prof(wl, WL_PROF_SEC);
+ sec = wl_read_prof(wl, dev, WL_PROF_SEC);
if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
params.cipher = WLAN_CIPHER_SUITE_WEP40;
WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
@@ -2774,15 +2806,15 @@
dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
CHECK_SYS_UP(wl);
- if (get_mode_by_netdev(wl, dev) == WL_MODE_AP) {
+ if (wl_get_mode_by_netdev(wl, dev) == WL_MODE_AP) {
err = wldev_iovar_getbuf(dev, "sta_info", (struct ether_addr *)mac,
- ETHER_ADDR_LEN, ioctlbuf, sizeof(ioctlbuf));
+ ETHER_ADDR_LEN, wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
if (err < 0) {
WL_ERR(("GET STA INFO failed, %d\n", err));
return err;
}
sinfo->filled = STATION_INFO_INACTIVE_TIME;
- sta = (sta_info_t *)ioctlbuf;
+ sta = (sta_info_t *)wl->ioctl_buf;
sta->len = dtoh16(sta->len);
sta->cap = dtoh16(sta->cap);
sta->flags = dtoh32(sta->flags);
@@ -2798,10 +2830,9 @@
bcm_ether_ntoa((const struct ether_addr *)mac, eabuf), sinfo->inactive_time,
sta->idle * 1000));
#endif
- } else if (get_mode_by_netdev(wl, dev) == WL_MODE_BSS) {
- u8 *curmacp = wl_read_prof(wl, WL_PROF_BSSID);
-
- if (!wl_get_drv_status(wl, CONNECTED) ||
+ } else if (wl_get_mode_by_netdev(wl, dev) == WL_MODE_BSS) {
+ u8 *curmacp = wl_read_prof(wl, dev, WL_PROF_BSSID);
+ if (!wl_get_drv_status(wl, CONNECTED, dev) ||
(dhd_is_associated(dhd, NULL) == FALSE)) {
WL_ERR(("NOT assoc\n"));
err = -ENODEV;
@@ -2841,7 +2872,7 @@
if (err) {
/* Disconnect due to zero BSSID or error to get RSSI */
WL_ERR(("force cfg80211_disconnected\n"));
- wl_clr_drv_status(wl, CONNECTED);
+ wl_clr_drv_status(wl, CONNECTED, dev);
cfg80211_disconnected(dev, 0, NULL, 0, GFP_KERNEL);
wl_link_down(wl);
}
@@ -2859,6 +2890,11 @@
struct wl_priv *wl = wiphy_priv(wiphy);
CHECK_SYS_UP(wl);
+
+ if (wl->p2p_net == dev) {
+ return err;
+ }
+
pm = enabled ? PM_FAST : PM_OFF;
/* Do not enable the power save after assoc if it is p2p interface */
if (wl->p2p && wl->p2p->vif_created) {
@@ -2908,11 +2944,11 @@
static s32 wl_cfg80211_resume(struct wiphy *wiphy)
{
struct wl_priv *wl = wiphy_priv(wiphy);
+ struct net_device *ndev = wl_to_prmry_ndev(wl);
s32 err = 0;
- if (unlikely(!wl_get_drv_status(wl, READY))) {
- WL_INFO(("device is not ready : status (%d)\n",
- (int)wl->status));
+ if (unlikely(!wl_get_drv_status(wl, READY, ndev))) {
+ WL_INFO(("device is not ready\n"));
return 0;
}
@@ -2929,33 +2965,38 @@
{
#ifdef DHD_CLEAR_ON_SUSPEND
struct wl_priv *wl = wiphy_priv(wiphy);
+ struct net_info *iter, *next;
struct net_device *ndev = wl_to_prmry_ndev(wl);
unsigned long flags;
- if (unlikely(!wl_get_drv_status(wl, READY))) {
+ if (unlikely(!wl_get_drv_status(wl, READY, ndev))) {
WL_INFO(("device is not ready : status (%d)\n",
(int)wl->status));
return 0;
}
-
- wl_set_drv_status(wl, SCAN_ABORTING);
+ for_each_ndev(wl, iter, next)
+ wl_set_drv_status(wl, SCAN_ABORTING, iter->ndev);
wl_term_iscan(wl);
- flags = dhd_os_spin_lock((dhd_pub_t *)(wl->pub));
+ spin_lock_irqsave(&wl->cfgdrv_lock, flags);
if (wl->scan_request) {
cfg80211_scan_done(wl->scan_request, true);
wl->scan_request = NULL;
}
- wl_clr_drv_status(wl, SCANNING);
- wl_clr_drv_status(wl, SCAN_ABORTING);
- dhd_os_spin_unlock((dhd_pub_t *)(wl->pub), flags);
- if (wl_get_drv_status(wl, CONNECTING)) {
- wl_bss_connect_done(wl, ndev, NULL, NULL, false);
+ for_each_ndev(wl, iter, next) {
+ wl_clr_drv_status(wl, SCANNING, iter->ndev);
+ wl_clr_drv_status(wl, SCAN_ABORTING, iter->ndev);
}
-#endif
+ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
+ for_each_ndev(wl, iter, next) {
+ if (wl_get_drv_status(wl, CONNECTING, iter->ndev)) {
+ wl_bss_connect_done(wl, iter->ndev, NULL, NULL, false);
+ }
+ }
+#endif /* DHD_CLEAR_ON_SUSPEND */
return 0;
}
-static __used s32
+static s32
wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list,
s32 err)
{
@@ -2963,9 +3004,12 @@
struct wl_priv *wl = wlcfg_drv_priv;
struct net_device *primary_dev = wl_to_prmry_ndev(wl);
- /* Firmware is supporting pmk list only for STA interface i.e. primary interface
+ if (!pmk_list) {
+ printk("pmk_list is NULL\n");
+ return -EINVAL;
+ }
+ /* pmk list is supported only for STA interface i.e. primary interface
* Refer code wlc_bsscfg.c->wlc_bsscfg_sta_init
- * Do we really need to support PMK cache in P2P in firmware?
*/
if (primary_dev != dev) {
WL_INFO(("Not supporting Flushing pmklist on virtual"
@@ -2982,8 +3026,8 @@
}
}
if (likely(!err)) {
- err = wl_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list,
- sizeof(*pmk_list));
+ err = wldev_iovar_setbuf(dev, "pmkid_info", (char *)pmk_list,
+ sizeof(*pmk_list), wl->ioctl_buf, WLC_IOCTL_MAXLEN, NULL);
}
return err;
@@ -3084,7 +3128,7 @@
}
-wl_scan_params_t *
+static wl_scan_params_t *
wl_cfg80211_scan_alloc_params(int channel, int nprobes, int *out_params_size)
{
wl_scan_params_t *params;
@@ -3145,13 +3189,13 @@
}
}
del_timer_sync(&wl->scan_timeout);
- flags = dhd_os_spin_lock((dhd_pub_t *)(wl->pub));
+ spin_lock_irqsave(&wl->cfgdrv_lock, flags);
if (wl->scan_request) {
cfg80211_scan_done(wl->scan_request, true);
wl->scan_request = NULL;
}
- wl_clr_drv_status(wl, SCANNING);
- dhd_os_spin_unlock((dhd_pub_t *)(wl->pub), flags);
+ wl_clr_drv_status(wl, SCANNING, ndev);
+ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
if (params)
kfree(params);
return err;
@@ -3164,36 +3208,49 @@
unsigned int duration, u64 *cookie)
{
s32 target_channel;
+ u32 id;
+ struct ether_addr primary_mac;
+ struct net_device *ndev = NULL;
s32 err = BCME_OK;
struct wl_priv *wl = wiphy_priv(wiphy);
- dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
WL_DBG(("Enter, netdev_ifidx: %d \n", dev->ifindex));
- if (likely(wl_get_drv_status(wl, SCANNING))) {
- wl_cfg80211_scan_abort(wl, dev);
+
+ if (wl->p2p_net == dev) {
+ ndev = wl_to_prmry_ndev(wl);
+ } else {
+ ndev = dev;
+ }
+
+ if (wl_get_drv_status(wl, SCANNING, ndev)) {
+ wl_cfg80211_scan_abort(wl, ndev);
}
target_channel = ieee80211_frequency_to_channel(channel->center_freq);
memcpy(&wl->remain_on_chan, channel, sizeof(struct ieee80211_channel));
wl->remain_on_chan_type = channel_type;
- wl->cache_cookie = *cookie;
+ id = ++wl->last_roc_id;
+ if (id == 0)
+ id = ++wl->last_roc_id;
+ *cookie = id;
cfg80211_ready_on_channel(dev, *cookie, channel,
channel_type, duration, GFP_KERNEL);
- if (!p2p_on(wl)) {
- wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p->dev_addr, &wl->p2p->int_addr);
+ if (!p2p_is_on(wl)) {
+ get_primary_mac(wl, &primary_mac);
+ wl_cfgp2p_generate_bss_mac(&primary_mac, &wl->p2p->dev_addr, &wl->p2p->int_addr);
/* In case of p2p_listen command, supplicant send remain_on_channel
* without turning on P2P
*/
p2p_on(wl) = true;
- err = wl_cfgp2p_enable_discovery(wl, dev, NULL, 0);
+ err = wl_cfgp2p_enable_discovery(wl, ndev, NULL, 0);
if (unlikely(err)) {
goto exit;
}
}
- if (p2p_on(wl))
+ if (p2p_is_on(wl))
wl_cfgp2p_discover_listen(wl, target_channel, duration);
@@ -3211,7 +3268,94 @@
}
static s32
-wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
+wl_cfg80211_send_pending_tx_act_frm(struct wl_priv *wl)
+{
+ wl_af_params_t *tx_act_frm;
+ struct net_device *dev = wl->afx_hdl->dev;
+ if (!p2p_is_on(wl))
+ return -1;
+
+ if (dev == wl->p2p_net) {
+ dev = wl_to_prmry_ndev(wl);
+ }
+
+ tx_act_frm = wl->afx_hdl->pending_tx_act_frm;
+ WL_DBG(("Sending the action frame\n"));
+ wl->afx_hdl->pending_tx_act_frm = NULL;
+ if (tx_act_frm != NULL) {
+ /* Suspend P2P discovery's search-listen to prevent it from
+ * starting a scan or changing the channel.
+ */
+ wl_clr_drv_status(wl, SENDING_ACT_FRM, wl->afx_hdl->dev);
+ wl_clr_drv_status(wl, SCANNING, wl->afx_hdl->dev);
+ wl_cfg80211_scan_abort(wl, dev);
+ wl_cfgp2p_discover_enable_search(wl, false);
+ tx_act_frm->channel = wl->afx_hdl->peer_chan;
+ wl->afx_hdl->ack_recv = (wl_cfgp2p_tx_action_frame(wl, dev,
+ tx_act_frm, wl->afx_hdl->bssidx)) ? false : true;
+ }
+ return 0;
+}
+static void
+wl_cfg80211_afx_handler(struct work_struct *work)
+{
+
+ struct afx_hdl *afx_instance;
+ struct wl_priv *wl = wlcfg_drv_priv;
+ afx_instance = container_of(work, struct afx_hdl, work);
+ if (afx_instance != NULL) {
+ wl_cfgp2p_act_frm_search(wl, wl->afx_hdl->dev,
+ wl->afx_hdl->bssidx, 0);
+ }
+}
+
+static bool
+wl_cfg80211_send_at_common_channel(struct wl_priv *wl,
+ struct net_device *dev,
+ wl_af_params_t *af_params)
+{
+ WL_DBG((" enter ) \n"));
+ /* initialize afx_hdl */
+ wl->afx_hdl->pending_tx_act_frm = af_params;
+ wl->afx_hdl->bssidx = wl_cfgp2p_find_idx(wl, dev);
+ wl->afx_hdl->dev = dev;
+ wl->afx_hdl->retry = 0;
+ wl->afx_hdl->peer_chan = WL_INVALID;
+ wl->afx_hdl->ack_recv = false;
+ memcpy(wl->afx_hdl->pending_tx_dst_addr.octet,
+ af_params->action_frame.da.octet,
+ sizeof(wl->afx_hdl->pending_tx_dst_addr.octet));
+ /* Loop to wait until we have sent the pending tx action frame or the
+ * pending action frame tx is cancelled.
+ */
+ while ((wl->afx_hdl->retry < WL_CHANNEL_SYNC_RETRY) &&
+ (wl->afx_hdl->peer_chan == WL_INVALID)) {
+ wl_set_drv_status(wl, SENDING_ACT_FRM, dev);
+ wl_set_drv_status(wl, SCANNING, dev);
+ WL_DBG(("Scheduling the action frame for sending.. retry %d\n",
+ wl->afx_hdl->retry));
+ /* Do find_peer_for_action */
+ schedule_work(&wl->afx_hdl->work);
+ wait_for_completion(&wl->act_frm_scan);
+ wl->afx_hdl->retry++;
+ }
+ if (wl->afx_hdl->peer_chan != WL_INVALID)
+ wl_cfg80211_send_pending_tx_act_frm(wl);
+ else {
+ WL_ERR(("Couldn't find the peer after %d retries\n",
+ wl->afx_hdl->retry));
+ }
+ wl->afx_hdl->dev = NULL;
+ wl->afx_hdl->bssidx = WL_INVALID;
+ wl_clr_drv_status(wl, SENDING_ACT_FRM, dev);
+ if (wl->afx_hdl->ack_recv)
+ return true; /* ACK */
+ else
+ return false; /* NO ACK */
+}
+
+static s32
+wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev,
struct ieee80211_channel *channel, bool offchan,
enum nl80211_channel_type channel_type,
bool channel_type_valid, unsigned int wait,
@@ -3221,29 +3365,39 @@
wl_af_params_t *af_params;
wifi_p2p_ie_t *p2p_ie;
wpa_ie_fixed_t *wps_ie;
+ scb_val_t scb_val;
const struct ieee80211_mgmt *mgmt;
struct wl_priv *wl = wiphy_priv(wiphy);
- dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
+ struct net_device *dev = NULL;
s32 err = BCME_OK;
s32 bssidx = 0;
u32 p2pie_len = 0;
u32 wpsie_len = 0;
- u16 fc;
+ u32 id;
+ u32 retry = 0;
bool ack = false;
- wifi_p2p_pub_act_frame_t *act_frm;
+ wifi_p2p_pub_act_frame_t *act_frm = NULL;
+ wifi_p2p_action_frame_t *p2p_act_frm = NULL;
+ wifi_p2psd_gas_pub_act_frame_t *sd_act_frm = NULL;
+ s8 eabuf[ETHER_ADDR_STR_LEN];
+
WL_DBG(("Enter \n"));
+
+ if (ndev == wl->p2p_net) {
+ dev = wl_to_prmry_ndev(wl);
+ } else {
+ /* If TX req is for any valid ifidx. Use as is */
+ dev = ndev;
+ }
+
/* find bssidx based on ndev */
bssidx = wl_cfgp2p_find_idx(wl, dev);
- /* cookie generation */
- *cookie = (unsigned long) buf;
-
if (bssidx == -1) {
WL_ERR(("Can not find the bssidx for dev( %p )\n", dev));
return -ENODEV;
}
- if (wl->p2p_supported && p2p_on(wl)) {
- wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p->dev_addr, &wl->p2p->int_addr);
+ if (p2p_is_on(wl)) {
/* Suspend P2P discovery search-listen to prevent it from changing the
* channel.
*/
@@ -3252,31 +3406,27 @@
return -EFAULT;
}
}
-
- mgmt = (const struct ieee80211_mgmt *) buf;
- fc = mgmt->frame_control;
- if (fc != IEEE80211_STYPE_ACTION) {
- if (fc == IEEE80211_STYPE_PROBE_RESP) {
+ *cookie = 0;
+ id = wl->send_action_id++;
+ if (id == 0)
+ id = wl->send_action_id++;
+ *cookie = id;
+ mgmt = (const struct ieee80211_mgmt *)buf;
+ if (ieee80211_is_mgmt(mgmt->frame_control)) {
+ if (ieee80211_is_probe_resp(mgmt->frame_control)) {
s32 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
s32 ie_len = len - ie_offset;
if ((p2p_ie = wl_cfgp2p_find_p2pie((u8 *)(buf + ie_offset), ie_len))
!= NULL) {
/* Total length of P2P Information Element */
p2pie_len = p2p_ie->len + sizeof(p2p_ie->len) + sizeof(p2p_ie->id);
- /* Have to change p2p device address in dev_info attribute
- * because Supplicant use primary eth0 address
- */
- #ifdef ENABLE_DRIVER_CHANGE_IFADDR /* We are now doing this in supplicant */
- wl_cfg80211_change_ifaddr((u8 *)p2p_ie,
- &wl->p2p_dev_addr, P2P_SEID_DEV_INFO);
- #endif
}
if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)(buf + ie_offset), ie_len))
!= NULL) {
/* Order of Vendor IE is 1) WPS IE +
* 2) P2P IE created by supplicant
* So, it is ok to find start address of WPS IE
- * to save IEs to firmware
+ * to save IEs
*/
wpsie_len = wps_ie->length + sizeof(wps_ie->length) +
sizeof(wps_ie->tag);
@@ -3284,18 +3434,36 @@
VNDR_IE_PRBRSP_FLAG,
(u8 *)wps_ie, wpsie_len + p2pie_len);
}
+ cfg80211_mgmt_tx_status(ndev, *cookie, buf, len, true, GFP_KERNEL);
+ goto exit;
+ } else if (ieee80211_is_disassoc(mgmt->frame_control) ||
+ ieee80211_is_deauth(mgmt->frame_control)) {
+ memcpy(scb_val.ea.octet, mgmt->da, ETH_ALEN);
+ scb_val.val = mgmt->u.disassoc.reason_code;
+ wldev_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scb_val,
+ sizeof(scb_val_t), true);
+ WL_DBG(("Disconnect STA : %s\n",
+ bcm_ether_ntoa((const struct ether_addr *)mgmt->da, eabuf)));
+ cfg80211_mgmt_tx_status(ndev, *cookie, buf, len, true, GFP_KERNEL);
+ goto exit;
+
+ } else if (ieee80211_is_action(mgmt->frame_control)) {
+ /* Abort the dwell time of any previous off-channel
+ * action frame that may be still in effect. Sending
+ * off-channel action frames relies on the driver's
+ * scan engine. If a previous off-channel action frame
+ * tx is still in progress (including the dwell time),
+ * then this new action frame will not be sent out.
+ */
+ wl_cfg80211_scan_abort(wl, dev);
+
}
- cfg80211_mgmt_tx_status(dev, *cookie, buf, len, true, GFP_KERNEL);
- goto exit;
+
} else {
- /* Abort the dwell time of any previous off-channel action frame that may
- * be still in effect. Sending off-channel action frames relies on the
- * driver's scan engine. If a previous off-channel action frame tx is
- * still in progress (including the dwell time), then this new action
- * frame will not be sent out.
- */
- wl_cfg80211_scan_abort(wl, dev);
+ WL_ERR(("Driver only allows MGMT packet type\n"));
+ goto exit;
}
+
af_params = (wl_af_params_t *) kzalloc(WL_WIFI_AF_PARAMS_SIZE, GFP_KERNEL);
if (af_params == NULL)
@@ -3307,7 +3475,7 @@
action_frame = &af_params->action_frame;
/* Add the packet Id */
- action_frame->packetId = (u32) action_frame;
+ action_frame->packetId = *cookie;
WL_DBG(("action frame %d\n", action_frame->packetId));
/* Add BSSID */
memcpy(&action_frame->da, &mgmt->da[0], ETHER_ADDR_LEN);
@@ -3321,6 +3489,14 @@
af_params->channel =
ieee80211_frequency_to_channel(channel->center_freq);
+ if (channel->band == IEEE80211_BAND_5GHZ) {
+ err = wldev_ioctl(dev, WLC_SET_CHANNEL,
+ &af_params->channel, sizeof(af_params->channel), true);
+ if (err < 0) {
+ WL_ERR(("WLC_SET_CHANNEL error %d\n", err));
+ }
+ }
+
/* Add the dwell time
* Dwell time to stay off-channel to wait for a response action frame
* after transmitting an GO Negotiation action frame
@@ -3328,28 +3504,82 @@
af_params->dwell_time = WL_DWELL_TIME;
memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN], action_frame->len);
+ if (wl_cfgp2p_is_pub_action(action_frame->data, action_frame->len)) {
+ act_frm = (wifi_p2p_pub_act_frame_t *) (action_frame->data);
+ WL_DBG(("P2P PUB action_frame->len: %d chan %d category %d subtype %d\n",
+ action_frame->len, af_params->channel,
+ act_frm->category, act_frm->subtype));
+ } else if (wl_cfgp2p_is_p2p_action(action_frame->data, action_frame->len)) {
+ p2p_act_frm = (wifi_p2p_action_frame_t *) (action_frame->data);
+ WL_DBG(("P2P action_frame->len: %d chan %d category %d subtype %d\n",
+ action_frame->len, af_params->channel,
+ p2p_act_frm->category, p2p_act_frm->subtype));
+ } else if (wl_cfgp2p_is_gas_action(action_frame->data, action_frame->len)) {
+ sd_act_frm = (wifi_p2psd_gas_pub_act_frame_t *) (action_frame->data);
+ WL_DBG(("Service Discovery action_frame->len: %d chan %d category %d action %d\n",
+ action_frame->len, af_params->channel,
+ sd_act_frm->category, sd_act_frm->action));
- act_frm = (wifi_p2p_pub_act_frame_t *) (action_frame->data);
- WL_DBG(("action_frame->len: %d chan %d category %d subtype %d\n",
- action_frame->len, af_params->channel,
- act_frm->category, act_frm->subtype));
- if (wl->p2p->vif_created) {
+ }
+ wl_cfgp2p_print_actframe(true, action_frame->data, action_frame->len);
/*
* To make sure to send successfully action frame, we have to turn off mpc
*/
- if ((act_frm->subtype == P2P_PAF_GON_REQ)||
- (act_frm->subtype == P2P_PAF_GON_RSP)) {
- wldev_iovar_setint(dev, "mpc", 0);
- } else if (act_frm->subtype == P2P_PAF_GON_CONF) {
- wldev_iovar_setint(dev, "mpc", 1);
- } else if (act_frm->subtype == P2P_PAF_DEVDIS_REQ) {
- af_params->dwell_time = WL_LONG_DWELL_TIME;
- }
+
+ if (act_frm && ((act_frm->subtype == P2P_PAF_GON_REQ) ||
+ (act_frm->subtype == P2P_PAF_GON_RSP) ||
+ (act_frm->subtype == P2P_PAF_GON_CONF) ||
+ (act_frm->subtype == P2P_PAF_PROVDIS_REQ))) {
+ wldev_iovar_setint(dev, "mpc", 0);
}
- ack = (wl_cfgp2p_tx_action_frame(wl, dev, af_params, bssidx)) ? false : true;
- cfg80211_mgmt_tx_status(dev, *cookie, buf, len, ack, GFP_KERNEL);
+ if (act_frm && act_frm->subtype == P2P_PAF_DEVDIS_REQ) {
+ af_params->dwell_time = WL_LONG_DWELL_TIME;
+ } else if (act_frm &&
+ (act_frm->subtype == P2P_PAF_PROVDIS_REQ ||
+ act_frm->subtype == P2P_PAF_PROVDIS_RSP ||
+ act_frm->subtype == P2P_PAF_GON_RSP)) {
+ af_params->dwell_time = WL_MED_DWELL_TIME;
+ }
+ if (IS_P2P_SOCIAL(af_params->channel) &&
+ (IS_P2P_PUB_ACT_REQ(act_frm, action_frame->len) ||
+ IS_GAS_REQ(sd_act_frm, action_frame->len)) &&
+ wl_to_p2p_bss_saved_ie(wl, P2PAPI_BSSCFG_DEVICE).p2p_probe_req_ie_len) {
+ /* channel offload require P2P IE for Probe request
+ * otherwise, we will use wl_cfgp2p_tx_action_frame directly.
+ * channel offload for action request frame
+ */
+
+ /* channel offload for action request frame */
+ ack = wl_cfg80211_send_at_common_channel(wl, dev, af_params);
+ } else {
+ ack = (wl_cfgp2p_tx_action_frame(wl, dev, af_params, bssidx)) ? false : true;
+ if (!ack) {
+ if (wl_to_p2p_bss_saved_ie(wl, P2PAPI_BSSCFG_DEVICE).p2p_probe_req_ie_len) {
+ /* if the NO ACK occurs, the peer device will be on
+ * listen channel of the peer
+ * So, we have to find the peer and send action frame on
+ * that channel.
+ */
+ ack = wl_cfg80211_send_at_common_channel(wl, dev, af_params);
+ } else {
+ for (retry = 0; retry < WL_CHANNEL_SYNC_RETRY; retry++) {
+ ack = (wl_cfgp2p_tx_action_frame(wl, dev,
+ af_params, bssidx)) ? false : true;
+ if (ack)
+ break;
+ }
+
+ }
+
+ }
+
+ }
+ cfg80211_mgmt_tx_status(ndev, *cookie, buf, len, ack, GFP_KERNEL);
+ if (act_frm && act_frm->subtype == P2P_PAF_GON_CONF) {
+ wldev_iovar_setint(dev, "mpc", 1);
+ }
kfree(af_params);
exit:
return err;
@@ -3403,7 +3633,11 @@
{
s32 channel;
s32 err = BCME_OK;
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ if (wl->p2p_net == dev) {
+ dev = wl_to_prmry_ndev(wl);
+ }
channel = ieee80211_frequency_to_channel(chan->center_freq);
WL_DBG(("netdev_ifidx(%d), chan_type(%d) target channel(%d) \n",
dev->ifindex, channel_type, channel));
@@ -3420,7 +3654,6 @@
s32 len = 0;
s32 err = BCME_OK;
u16 auth = 0; /* d11 open authentication */
- u16 count;
u32 wsec;
u32 pval = 0;
u32 gval = 0;
@@ -3458,7 +3691,7 @@
len -= WPA_SUITE_LEN;
/* check the unicast cipher */
ucast = (wpa_suite_ucast_t *)&mcast[1];
- count = ltoh16_ua(&ucast->count);
+ ltoh16_ua(&ucast->count);
tmp = ucast->list[0].oui;
switch (tmp[DOT11_OUI_LEN]) {
case WPA_CIPHER_NONE:
@@ -3481,7 +3714,7 @@
wsec = (pval | gval | SES_OW_ENABLED);
/* check the AKM */
mgmt = (wpa_suite_auth_key_mgmt_t *)&ucast->list[1];
- count = ltoh16_ua(&mgmt->count);
+ ltoh16_ua(&mgmt->count);
tmp = (u8 *)&mgmt->list[0];
switch (tmp[DOT11_OUI_LEN]) {
case RSN_AKM_NONE:
@@ -3684,13 +3917,19 @@
u16 p2pie_len = 0;
u8 beacon_ie[IE_MAX_LEN];
s32 ie_offset = 0;
- s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
+ s32 bssidx = 0;
s32 infra = 1;
s32 join_params_size = 0;
s32 ap = 0;
WL_DBG(("interval (%d) dtim_period (%d) head_len (%d) tail_len (%d)\n",
info->interval, info->dtim_period, info->head_len, info->tail_len));
- if (wl->p2p_supported && p2p_on(wl) &&
+
+ if (wl->p2p_net == dev) {
+ dev = wl_to_prmry_ndev(wl);
+ }
+
+ bssidx = wl_cfgp2p_find_idx(wl, dev);
+ if (p2p_is_on(wl) &&
(bssidx == wl_to_p2p_bss_bssidx(wl,
P2PAPI_BSSCFG_CONNECTION))) {
memset(beacon_ie, 0, sizeof(beacon_ie));
@@ -3728,19 +3967,13 @@
if ((p2p_ie = wl_cfgp2p_find_p2pie((u8 *)info->tail, info->tail_len)) != NULL) {
/* Total length of P2P Information Element */
p2pie_len = p2p_ie->len + sizeof(p2p_ie->len) + sizeof(p2p_ie->id);
- #ifdef ENABLE_DRIVER_CHANGE_IFADDR /* We are now doing this in supplicant */
- /* Have to change device address in dev_id attribute because Supplicant
- * use primary eth0 address
- */
- wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p_dev_addr, P2P_SEID_DEV_ID);
- #endif
memcpy(&beacon_ie[wpsie_len], p2p_ie, p2pie_len);
} else {
WL_ERR(("No P2PIE in beacon \n"));
}
/* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */
- wl_dongle_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc);
+ wl_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc);
wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_BEACON_FLAG,
beacon_ie, wpsie_len + p2pie_len);
@@ -3763,17 +3996,18 @@
goto exit;
}
err = wldev_iovar_setbuf_bsscfg(dev, "ssid", &wl->p2p->ssid,
- sizeof(wl->p2p->ssid), ioctlbuf, sizeof(ioctlbuf), bssidx);
+ sizeof(wl->p2p->ssid), wl->ioctl_buf, WLC_IOCTL_MAXLEN,
+ bssidx, &wl->ioctl_buf_sync);
if (err < 0) {
WL_ERR(("GO SSID setting error %d\n", err));
goto exit;
}
- if ((err = wl_cfgp2p_bss(dev, bssidx, 1)) < 0) {
+ if ((err = wl_cfgp2p_bss(wl, dev, bssidx, 1)) < 0) {
WL_ERR(("GO Bring up error %d\n", err));
goto exit;
}
}
- } else if (wl_get_drv_status(wl, AP_CREATING)) {
+ } else if (wl_get_drv_status(wl, AP_CREATING, dev)) {
ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
ap = 1;
/* find the SSID */
@@ -3848,7 +4082,7 @@
beacon_ie, wpsie_len);
wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL);
/* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */
- wl_dongle_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc);
+ wl_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc);
} else {
WL_DBG(("No WPSIE in beacon \n"));
}
@@ -3879,11 +4113,11 @@
/* create softap */
if ((err = wldev_ioctl(dev, WLC_SET_SSID, &join_params,
join_params_size, true)) == 0) {
- wl_clr_drv_status(wl, AP_CREATING);
- wl_set_drv_status(wl, AP_CREATED);
+ wl_clr_drv_status(wl, AP_CREATING, dev);
+ wl_set_drv_status(wl, AP_CREATED, dev);
}
}
- } else if (wl_get_drv_status(wl, AP_CREATED)) {
+ } else if (wl_get_drv_status(wl, AP_CREATED, dev)) {
ap = 1;
/* find the WPSIE */
if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)info->tail, info->tail_len)) != NULL) {
@@ -3901,12 +4135,12 @@
kfree(wl->ap_info->wps_ie);
wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL);
/* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */
- wl_dongle_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc);
+ wl_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc);
} else if (wl->ap_info->wps_ie == NULL) {
WL_DBG((" WPS IE is added\n"));
wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL);
/* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */
- wl_dongle_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc);
+ wl_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc);
}
/* find the RSN_IE */
if ((wpa2_ie = bcm_parse_tlvs((u8 *)info->tail, info->tail_len,
@@ -3972,12 +4206,12 @@
}
if (update_bss) {
wl->ap_info->security_mode = true;
- wl_cfgp2p_bss(dev, bssidx, 0);
+ wl_cfgp2p_bss(wl, dev, bssidx, 0);
if (wl_validate_wpa2ie(dev, wpa2_ie, bssidx) < 0 ||
wl_validate_wpaie(dev, wpa_ie, bssidx) < 0) {
return BCME_ERROR;
}
- wl_cfgp2p_bss(dev, bssidx, 1);
+ wl_cfgp2p_bss(wl, dev, bssidx, 1);
}
}
} else {
@@ -4024,7 +4258,7 @@
.add_beacon = wl_cfg80211_add_set_beacon,
};
-static s32 wl_mode_to_nl80211_iftype(s32 mode)
+s32 wl_mode_to_nl80211_iftype(s32 mode)
{
s32 err = 0;
@@ -4042,21 +4276,15 @@
return err;
}
-static struct wireless_dev *wl_alloc_wdev(struct device *sdiofunc_dev)
+static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev)
{
- struct wireless_dev *wdev;
s32 err = 0;
- wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
- if (unlikely(!wdev)) {
- WL_ERR(("Could not allocate wireless device\n"));
- return ERR_PTR(-ENOMEM);
- }
wdev->wiphy =
wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv));
if (unlikely(!wdev->wiphy)) {
WL_ERR(("Couldn not allocate wiphy device\n"));
err = -ENOMEM;
- goto wiphy_new_out;
+ return err;
}
set_wiphy_dev(wdev->wiphy, sdiofunc_dev);
wdev->wiphy->max_scan_ie_len = WL_SCAN_IE_LEN_MAX;
@@ -4064,8 +4292,8 @@
wdev->wiphy->max_scan_ssids = WL_SCAN_PARAMS_SSID_MAX;
wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
wdev->wiphy->interface_modes =
- BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC)
- | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR);
+ BIT(NL80211_IFTYPE_STATION)
+ | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR);
wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a;
@@ -4085,7 +4313,9 @@
WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS |
#endif
WIPHY_FLAG_4ADDR_STATION;
-
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
+ wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
+#endif
WL_DBG(("Registering custom regulatory)\n"));
wdev->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
wiphy_apply_custom_regulatory(wdev->wiphy, &brcm_regdom);
@@ -4093,39 +4323,28 @@
err = wiphy_register(wdev->wiphy);
if (unlikely(err < 0)) {
WL_ERR(("Couldn not register wiphy device (%d)\n", err));
- goto wiphy_register_out;
+ wiphy_free(wdev->wiphy);
}
- return wdev;
-
-wiphy_register_out:
- wiphy_free(wdev->wiphy);
-
-wiphy_new_out:
- kfree(wdev);
-
- return ERR_PTR(err);
+ return err;
}
static void wl_free_wdev(struct wl_priv *wl)
{
- int i;
struct wireless_dev *wdev = wl->wdev;
-
- if (unlikely(!wdev)) {
+ struct wiphy *wiphy;
+ if (!wdev) {
WL_ERR(("wdev is invalid\n"));
return;
}
-
- for (i = 0; i < VWDEV_CNT; i++) {
- if ((wl->vwdev[i] != NULL)) {
- kfree(wl->vwdev[i]);
- wl->vwdev[i] = NULL;
- }
- }
+ wiphy = wdev->wiphy;
wiphy_unregister(wdev->wiphy);
wdev->wiphy->dev.parent = NULL;
- wiphy_free(wdev->wiphy);
- kfree(wdev);
+
+ wl_delete_all_netinfo(wl);
+ wiphy_free(wiphy);
+ /* PLEASE do NOT call any function after wiphy_free, the driver's private structure "wl",
+ * which is the private part of wiphy, has been freed in wiphy_free !!!!!!!!!!!
+ */
}
static s32 wl_inform_bss(struct wl_priv *wl)
@@ -4155,6 +4374,7 @@
struct wl_cfg80211_bss_info *notif_bss_info;
struct wl_scan_req *sr = wl_to_sr(wl);
struct beacon_proberesp *beacon_proberesp;
+ struct cfg80211_bss *cbss = NULL;
s32 mgmt_type;
s32 signal;
u32 freq;
@@ -4213,13 +4433,31 @@
signal = notif_bss_info->rssi * 100;
- if (unlikely(!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
- le16_to_cpu(notif_bss_info->frame_len),
- signal, GFP_KERNEL))) {
+#if defined(WLP2P) && ENABLE_P2P_INTERFACE
+ if (wl->p2p_net && wl->scan_request &&
+ wl->scan_request->dev == wl->p2p_net) {
+#else
+ if (p2p_is_on(wl) && p2p_scan(wl)) {
+#endif
+ /* find the P2PIE, if we do not find it, we will discard this frame */
+ wifi_p2p_ie_t * p2p_ie;
+ if ((p2p_ie = wl_cfgp2p_find_p2pie((u8 *)beacon_proberesp->variable,
+ wl_get_ielen(wl))) == NULL) {
+ WL_ERR(("Couldn't find P2PIE in probe response/beacon\n"));
+ kfree(notif_bss_info);
+ return err;
+ }
+ }
+
+ cbss = cfg80211_inform_bss_frame(wiphy, channel, mgmt,
+ le16_to_cpu(notif_bss_info->frame_len), signal, GFP_KERNEL);
+ if (unlikely(!cbss)) {
WL_ERR(("cfg80211_inform_bss_frame error\n"));
kfree(notif_bss_info);
return -EINVAL;
}
+
+ cfg80211_put_bss(cbss);
kfree(notif_bss_info);
return err;
@@ -4277,108 +4515,156 @@
return false;
}
+/* The mainline kernel >= 3.2.0 has support for indicating new/del station
+ * to AP/P2P GO via events. If this change is backported to kernel for which
+ * this driver is being built, set CFG80211_STA_EVENT_AVAILABLE to 1. You
+ * should use this new/del sta event mechanism for BRCM supplicant from BRANCH
+ * HOSTAP_BRANCH_0_15 (ver >= 15_1).
+ */
+#define CFG80211_STA_EVENT_AVAILABLE 0
static s32
-wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
+wl_notify_connect_status_ap(struct wl_priv *wl, struct net_device *ndev,
const wl_event_msg_t *e, void *data)
{
- bool act;
- bool isfree = false;
s32 err = 0;
- s32 freq;
- s32 channel;
- u8 body[200];
u32 event = ntoh32(e->event_type);
u32 reason = ntoh32(e->reason);
u32 len = ntoh32(e->datalen);
- u16 fc = 0;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !CFG80211_STA_EVENT_AVAILABLE
+ bool isfree = false;
u8 *mgmt_frame;
u8 bsscfgidx = e->bsscfgidx;
+ s32 freq;
+ s32 channel;
+ u8 body[200];
+ u16 fc = 0;
struct ieee80211_supported_band *band;
struct ether_addr da;
struct ether_addr bssid;
struct wiphy *wiphy = wl_to_wiphy(wl);
channel_info_t ci;
+#else
+ struct station_info sinfo;
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !CFG80211_STA_EVENT_AVAILABLE */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !CFG80211_STA_EVENT_AVAILABLE
memset(body, 0, sizeof(body));
memset(&bssid, 0, ETHER_ADDR_LEN);
WL_DBG(("Enter \n"));
+ if (wl_get_mode_by_netdev(wl, ndev) == WL_INVALID)
+ return WL_INVALID;
- if (get_mode_by_netdev(wl, ndev) == WL_MODE_AP) {
- memcpy(body, data, len);
- wldev_iovar_getbuf_bsscfg(ndev, "cur_etheraddr",
- NULL, 0, ioctlbuf, sizeof(ioctlbuf), bsscfgidx);
- memcpy(da.octet, ioctlbuf, ETHER_ADDR_LEN);
- err = wldev_ioctl(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false);
- switch (event) {
- case WLC_E_ASSOC_IND:
- fc = FC_ASSOC_REQ;
- break;
- case WLC_E_REASSOC_IND:
- fc = FC_REASSOC_REQ;
- break;
- case WLC_E_DISASSOC_IND:
- fc = FC_DISASSOC;
- break;
- case WLC_E_DEAUTH_IND:
- fc = FC_DISASSOC;
- break;
- case WLC_E_DEAUTH:
- fc = FC_DISASSOC;
- break;
- default:
- fc = 0;
- goto exit;
- }
- if ((err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &ci, sizeof(ci), false)))
- return err;
+ memcpy(body, data, len);
+ wldev_iovar_getbuf_bsscfg(ndev, "cur_etheraddr",
+ NULL, 0, wl->ioctl_buf, WLC_IOCTL_MAXLEN, bsscfgidx, &wl->ioctl_buf_sync);
+ memcpy(da.octet, wl->ioctl_buf, ETHER_ADDR_LEN);
+ err = wldev_ioctl(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false);
+ switch (event) {
+ case WLC_E_ASSOC_IND:
+ fc = FC_ASSOC_REQ;
+ break;
+ case WLC_E_REASSOC_IND:
+ fc = FC_REASSOC_REQ;
+ break;
+ case WLC_E_DISASSOC_IND:
+ fc = FC_DISASSOC;
+ break;
+ case WLC_E_DEAUTH_IND:
+ fc = FC_DISASSOC;
+ break;
+ case WLC_E_DEAUTH:
+ fc = FC_DISASSOC;
+ break;
+ default:
+ fc = 0;
+ goto exit;
+ }
+ if ((err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &ci, sizeof(ci), false)))
+ return err;
- channel = dtoh32(ci.hw_channel);
- if (channel <= CH_MAX_2G_CHANNEL)
- band = wiphy->bands[IEEE80211_BAND_2GHZ];
- else
- band = wiphy->bands[IEEE80211_BAND_5GHZ];
+ channel = dtoh32(ci.hw_channel);
+ if (channel <= CH_MAX_2G_CHANNEL)
+ band = wiphy->bands[IEEE80211_BAND_2GHZ];
+ else
+ band = wiphy->bands[IEEE80211_BAND_5GHZ];
#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
- freq = ieee80211_channel_to_frequency(channel);
+ freq = ieee80211_channel_to_frequency(channel);
#else
- freq = ieee80211_channel_to_frequency(channel, band->band);
+ freq = ieee80211_channel_to_frequency(channel, band->band);
#endif
- err = wl_frame_get_mgmt(fc, &da, &e->addr, &bssid,
+ err = wl_frame_get_mgmt(fc, &da, &e->addr, &bssid,
&mgmt_frame, &len, body);
- if (err < 0)
- goto exit;
- isfree = true;
+ if (err < 0)
+ goto exit;
+ isfree = true;
- if (event == WLC_E_ASSOC_IND && reason == DOT11_SC_SUCCESS) {
- cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC);
- } else if (event == WLC_E_DISASSOC_IND) {
- cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC);
- } else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) {
- cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC);
+ if (event == WLC_E_ASSOC_IND && reason == DOT11_SC_SUCCESS) {
+ cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC);
+ } else if (event == WLC_E_DISASSOC_IND) {
+ cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC);
+ } else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) {
+ cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC);
+ }
+
+exit:
+ if (isfree)
+ kfree(mgmt_frame);
+ return err;
+#else /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0) && !CFG80211_STA_EVENT_AVAILABLE */
+ sinfo.filled = 0;
+ if (((event == WLC_E_ASSOC_IND) || (event == WLC_E_REASSOC_IND)) &&
+ reason == DOT11_SC_SUCCESS) {
+ sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
+ if (!data) {
+ WL_ERR(("No IEs present in ASSOC/REASSOC_IND"));
+ return -EINVAL;
}
+ sinfo.assoc_req_ies = data;
+ sinfo.assoc_req_ies_len = len;
+ cfg80211_new_sta(ndev, e->addr.octet, &sinfo, GFP_ATOMIC);
+ } else if (event == WLC_E_DISASSOC_IND) {
+ cfg80211_del_sta(ndev, e->addr.octet, GFP_ATOMIC);
+ } else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) {
+ cfg80211_del_sta(ndev, e->addr.octet, GFP_ATOMIC);
+ }
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0) && !CFG80211_STA_EVENT_AVAILABLE */
+ return err;
+}
+static s32
+wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e, void *data)
+{
+ bool act;
+ s32 err = 0;
+ u32 event = ntoh32(e->event_type);
+
+ if (wl_get_mode_by_netdev(wl, ndev) == WL_MODE_AP) {
+ wl_notify_connect_status_ap(wl, ndev, e, data);
} else {
WL_DBG(("wl_notify_connect_status : event %d status : %d \n",
ntoh32(e->event_type), ntoh32(e->status)));
if (wl_is_linkup(wl, e, ndev)) {
wl_link_up(wl);
act = true;
- wl_update_prof(wl, e, &act, WL_PROF_ACT);
- wl_update_prof(wl, NULL, (void *)(e->addr.octet), WL_PROF_BSSID);
+ wl_update_prof(wl, ndev, e, &act, WL_PROF_ACT);
+ wl_update_prof(wl, ndev, NULL, (void *)&e->addr, WL_PROF_BSSID);
if (wl_is_ibssmode(wl, ndev)) {
printk("cfg80211_ibss_joined\n");
cfg80211_ibss_joined(ndev, (s8 *)&e->addr,
GFP_KERNEL);
WL_DBG(("joined in IBSS network\n"));
} else {
- if (!wl_get_drv_status(wl, DISCONNECTING)) {
- printk("wl_bss_connect_done succeeded status=(0x%x)\n",
- (int)wl->status);
+ if (!wl_get_drv_status(wl, DISCONNECTING, ndev)) {
+ printk("wl_bss_connect_done succeeded\n");
wl_bss_connect_done(wl, ndev, e, data, true);
WL_DBG(("joined in BSS network \"%s\"\n",
((struct wlc_ssid *)
- wl_read_prof(wl, WL_PROF_SSID))->SSID));
+ wl_read_prof(wl, ndev, WL_PROF_SSID))->SSID));
}
}
@@ -4386,15 +4672,15 @@
if (wl->scan_request) {
del_timer_sync(&wl->scan_timeout);
if (wl->escan_on) {
- wl_notify_escan_complete(wl, true);
+ wl_notify_escan_complete(wl, ndev, true);
} else
wl_iscan_aborted(wl);
}
- if (wl_get_drv_status(wl, CONNECTED)) {
+ if (wl_get_drv_status(wl, CONNECTED, ndev)) {
scb_val_t scbval;
- u8 *curbssid = wl_read_prof(wl, WL_PROF_BSSID);
+ u8 *curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID);
printk("link down, call cfg80211_disconnected\n");
- wl_clr_drv_status(wl, CONNECTED);
+ wl_clr_drv_status(wl, CONNECTED, ndev);
/* To make sure disconnect, explictly send dissassoc
* for BSSID 00:00:00:00:00:00 issue
*/
@@ -4406,12 +4692,12 @@
sizeof(scb_val_t), true);
cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
wl_link_down(wl);
- wl_init_prof(wl);
- } else if (wl_get_drv_status(wl, CONNECTING)) {
+ wl_init_prof(wl, ndev);
+ } else if (wl_get_drv_status(wl, CONNECTING, ndev)) {
printk("link down, during connecting\n");
wl_bss_connect_done(wl, ndev, e, data, false);
}
- wl_clr_drv_status(wl, DISCONNECTING);
+ wl_clr_drv_status(wl, DISCONNECTING, ndev);
} else if (wl_is_nonetwork(wl, e)) {
printk("connect failed event=%d e->status 0x%x\n",
@@ -4420,19 +4706,16 @@
if (wl->scan_request) {
del_timer_sync(&wl->scan_timeout);
if (wl->escan_on) {
- wl_notify_escan_complete(wl, true);
+ wl_notify_escan_complete(wl, ndev, true);
} else
wl_iscan_aborted(wl);
}
- if (wl_get_drv_status(wl, CONNECTING))
+ if (wl_get_drv_status(wl, CONNECTING, ndev))
wl_bss_connect_done(wl, ndev, e, data, false);
} else {
printk("%s nothing\n", __FUNCTION__);
}
}
-exit:
- if (isfree)
- kfree(mgmt_frame);
return err;
}
@@ -4446,50 +4729,17 @@
u32 status = be32_to_cpu(e->status);
WL_DBG(("Enter \n"));
if (event == WLC_E_ROAM && status == WLC_E_STATUS_SUCCESS) {
- if (wl_get_drv_status(wl, CONNECTED))
+ if (wl_get_drv_status(wl, CONNECTED, ndev))
wl_bss_roaming_done(wl, ndev, e, data);
else
wl_bss_connect_done(wl, ndev, e, data, true);
act = true;
- wl_update_prof(wl, e, &act, WL_PROF_ACT);
- wl_update_prof(wl, NULL, (void *)(e->addr.octet), WL_PROF_BSSID);
+ wl_update_prof(wl, ndev, e, &act, WL_PROF_ACT);
+ wl_update_prof(wl, ndev, NULL, (void *)&e->addr, WL_PROF_BSSID);
}
return err;
}
-static __used s32
-wl_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len)
-{
- struct wl_priv *wl = wlcfg_drv_priv;
- u32 buflen;
-
- buflen = bcm_mkiovar(name, buf, len, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
- BUG_ON(unlikely(!buflen));
-
- return wldev_ioctl(dev, WLC_SET_VAR, wl->ioctl_buf, buflen, true);
-}
-
-static s32
-wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
- s32 buf_len)
-{
- struct wl_priv *wl = wlcfg_drv_priv;
- u32 len;
- s32 err = 0;
-
- len = bcm_mkiovar(name, NULL, 0, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
- BUG_ON(unlikely(!len));
- err = wldev_ioctl(dev, WLC_GET_VAR, (void *)wl->ioctl_buf,
- WL_IOCTL_LEN_MAX, false);
- if (unlikely(err)) {
- WL_ERR(("error (%d)\n", err));
- return err;
- }
- memcpy(buf, wl->ioctl_buf, buf_len);
-
- return err;
-}
-
static s32 wl_get_assoc_ies(struct wl_priv *wl, struct net_device *ndev)
{
wl_assoc_info_t assoc_info;
@@ -4497,8 +4747,8 @@
s32 err = 0;
WL_DBG(("Enter \n"));
- err = wl_dev_bufvar_get(ndev, "assoc_info", wl->extra_buf,
- WL_ASSOC_INFO_MAX);
+ err = wldev_iovar_getbuf(ndev, "assoc_info", NULL, 0, wl->extra_buf,
+ WL_ASSOC_INFO_MAX, NULL);
if (unlikely(err)) {
WL_ERR(("could not get assoc info (%d)\n", err));
return err;
@@ -4516,8 +4766,8 @@
bzero(conn_info->resp_ie, sizeof(conn_info->resp_ie));
}
if (assoc_info.req_len) {
- err = wl_dev_bufvar_get(ndev, "assoc_req_ies", wl->extra_buf,
- WL_ASSOC_INFO_MAX);
+ err = wldev_iovar_getbuf(ndev, "assoc_req_ies", NULL, 0, wl->extra_buf,
+ WL_ASSOC_INFO_MAX, NULL);
if (unlikely(err)) {
WL_ERR(("could not get assoc req (%d)\n", err));
return err;
@@ -4537,8 +4787,8 @@
conn_info->req_ie_len = 0;
}
if (assoc_info.resp_len) {
- err = wl_dev_bufvar_get(ndev, "assoc_resp_ies", wl->extra_buf,
- WL_ASSOC_INFO_MAX);
+ err = wldev_iovar_getbuf(ndev, "assoc_resp_ies", NULL, 0, wl->extra_buf,
+ WL_ASSOC_INFO_MAX, NULL);
if (unlikely(err)) {
WL_ERR(("could not get assoc resp (%d)\n", err));
return err;
@@ -4600,8 +4850,8 @@
struct wl_bss_info *bi;
struct wlc_ssid *ssid;
struct bcm_tlv *tim;
- u16 beacon_interval;
- u8 dtim_period;
+ s32 beacon_interval;
+ s32 dtim_period;
size_t ie_len;
u8 *ie;
u8 *curbssid;
@@ -4612,14 +4862,14 @@
if (wl_is_ibssmode(wl, ndev))
return err;
- ssid = (struct wlc_ssid *)wl_read_prof(wl, WL_PROF_SSID);
- curbssid = wl_read_prof(wl, WL_PROF_BSSID);
+ ssid = (struct wlc_ssid *)wl_read_prof(wl, ndev, WL_PROF_SSID);
+ curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID);
bss = cfg80211_get_bss(wiphy, NULL, curbssid,
ssid->SSID, ssid->SSID_len, WLAN_CAPABILITY_ESS,
WLAN_CAPABILITY_ESS);
mutex_lock(&wl->usr_sync);
- if (unlikely(!bss)) {
+ if (!bss) {
WL_DBG(("Could not find the AP\n"));
*(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX);
err = wldev_ioctl(ndev, WLC_GET_BSS_INFO,
@@ -4655,7 +4905,7 @@
/*
* active scan was done so we could not get dtim
* information out of probe response.
- * so we speficially query dtim information to dongle.
+ * so we speficially query dtim information.
*/
err = wldev_ioctl(ndev, WLC_GET_DTIMPRD,
&dtim_period, sizeof(dtim_period), false);
@@ -4665,8 +4915,8 @@
}
}
- wl_update_prof(wl, NULL, &beacon_interval, WL_PROF_BEACONINT);
- wl_update_prof(wl, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
+ wl_update_prof(wl, ndev, NULL, &beacon_interval, WL_PROF_BEACONINT);
+ wl_update_prof(wl, ndev, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
update_bss_info_out:
mutex_unlock(&wl->usr_sync);
@@ -4682,8 +4932,8 @@
u8 *curbssid;
wl_get_assoc_ies(wl, ndev);
- wl_update_prof(wl, NULL, (void *)(e->addr.octet), WL_PROF_BSSID);
- curbssid = wl_read_prof(wl, WL_PROF_BSSID);
+ wl_update_prof(wl, ndev, NULL, (void *)(e->addr.octet), WL_PROF_BSSID);
+ curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID);
wl_update_bss_info(wl, ndev);
wl_update_pmklist(ndev, wl->pmk_list, err);
cfg80211_roamed(ndev,
@@ -4695,7 +4945,7 @@
conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
WL_DBG(("Report roaming result\n"));
- wl_set_drv_status(wl, CONNECTED);
+ wl_set_drv_status(wl, CONNECTED, ndev);
return err;
}
@@ -4706,20 +4956,21 @@
{
struct wl_connect_info *conn_info = wl_to_conn(wl);
s32 err = 0;
- u8 *curbssid = wl_read_prof(wl, WL_PROF_BSSID);
+ u8 *curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID);
+
WL_DBG((" enter\n"));
if (wl->scan_request) {
wl_cfg80211_scan_abort(wl, ndev);
}
- if (wl_get_drv_status(wl, CONNECTING)) {
- wl_clr_drv_status(wl, CONNECTING);
+ if (wl_get_drv_status(wl, CONNECTING, ndev)) {
+ wl_clr_drv_status(wl, CONNECTING, ndev);
if (completed) {
wl_get_assoc_ies(wl, ndev);
- wl_update_prof(wl, NULL, (void *)(e->addr.octet), WL_PROF_BSSID);
- curbssid = wl_read_prof(wl, WL_PROF_BSSID);
+ wl_update_prof(wl, ndev, NULL, (void *)(e->addr.octet), WL_PROF_BSSID);
+ curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID);
wl_update_bss_info(wl, ndev);
wl_update_pmklist(ndev, wl->pmk_list, err);
- wl_set_drv_status(wl, CONNECTED);
+ wl_set_drv_status(wl, CONNECTED, ndev);
}
cfg80211_connect_result(ndev,
curbssid,
@@ -4758,6 +5009,19 @@
}
static s32
+wl_notify_pfn_status(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e, void *data)
+{
+ WL_ERR((" PNO Event\n"));
+
+ mutex_lock(&wl->usr_sync);
+ /* TODO: Use cfg80211_sched_scan_results(wiphy); */
+ cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
+ mutex_unlock(&wl->usr_sync);
+ return 0;
+}
+
+static s32
wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
const wl_event_msg_t *e, void *data)
{
@@ -4768,11 +5032,15 @@
unsigned long flags;
WL_DBG(("Enter \n"));
+ if (!wl_get_drv_status(wl, SCANNING, ndev)) {
+ WL_ERR(("scan is not ready \n"));
+ return err;
+ }
if (wl->iscan_on && wl->iscan_kickstart)
return wl_wakeup_iscan(wl_to_iscan(wl));
mutex_lock(&wl->usr_sync);
- wl_clr_drv_status(wl, SCANNING);
+ wl_clr_drv_status(wl, SCANNING, ndev);
err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform,
sizeof(channel_inform), false);
if (unlikely(err)) {
@@ -4803,13 +5071,13 @@
scan_done_out:
del_timer_sync(&wl->scan_timeout);
- flags = dhd_os_spin_lock((dhd_pub_t *)(wl->pub));
+ spin_lock_irqsave(&wl->cfgdrv_lock, flags);
if (wl->scan_request) {
WL_DBG(("cfg80211_scan_done\n"));
cfg80211_scan_done(wl->scan_request, false);
wl->scan_request = NULL;
}
- dhd_os_spin_unlock((dhd_pub_t *)(wl->pub), flags);
+ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
mutex_unlock(&wl->usr_sync);
return err;
}
@@ -4865,7 +5133,10 @@
bool isfree = false;
s32 err = 0;
s32 freq;
- wifi_p2p_pub_act_frame_t *act_frm;
+ struct net_device *dev = NULL;
+ wifi_p2p_pub_act_frame_t *act_frm = NULL;
+ wifi_p2p_action_frame_t *p2p_act_frm = NULL;
+ wifi_p2psd_gas_pub_act_frame_t *sd_act_frm = NULL;
wl_event_rx_frame_data_t *rxframe =
(wl_event_rx_frame_data_t*)data;
u32 event = ntoh32(e->event_type);
@@ -4875,6 +5146,13 @@
u16 channel = ((ntoh16(rxframe->channel) & WL_CHANSPEC_CHAN_MASK));
memset(&bssid, 0, ETHER_ADDR_LEN);
+
+ if (wl->p2p_net == ndev) {
+ dev = wl_to_prmry_ndev(wl);
+ } else {
+ dev = ndev;
+ }
+
if (channel <= CH_MAX_2G_CHANNEL)
band = wiphy->bands[IEEE80211_BAND_2GHZ];
else
@@ -4886,11 +5164,11 @@
freq = ieee80211_channel_to_frequency(channel, band->band);
#endif
if (event == WLC_E_ACTION_FRAME_RX) {
- wldev_iovar_getbuf_bsscfg(ndev, "cur_etheraddr",
- NULL, 0, ioctlbuf, sizeof(ioctlbuf), bsscfgidx);
+ wldev_iovar_getbuf_bsscfg(dev, "cur_etheraddr",
+ NULL, 0, wl->ioctl_buf, WLC_IOCTL_MAXLEN, bsscfgidx, &wl->ioctl_buf_sync);
- wldev_ioctl(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false);
- memcpy(da.octet, ioctlbuf, ETHER_ADDR_LEN);
+ wldev_ioctl(dev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false);
+ memcpy(da.octet, wl->ioctl_buf, ETHER_ADDR_LEN);
err = wl_frame_get_mgmt(FC_ACTION, &da, &e->addr, &bssid,
&mgmt_frame, &mgmt_frame_len,
(u8 *)((wl_event_rx_frame_data_t *)rxframe + 1));
@@ -4900,13 +5178,29 @@
goto exit;
}
isfree = true;
- act_frm =
- (wifi_p2p_pub_act_frame_t *) (&mgmt_frame[DOT11_MGMT_HDR_LEN]);
+ if (wl_cfgp2p_is_pub_action(&mgmt_frame[DOT11_MGMT_HDR_LEN],
+ mgmt_frame_len - DOT11_MGMT_HDR_LEN)) {
+ act_frm = (wifi_p2p_pub_act_frame_t *)
+ (&mgmt_frame[DOT11_MGMT_HDR_LEN]);
+ } else if (wl_cfgp2p_is_p2p_action(&mgmt_frame[DOT11_MGMT_HDR_LEN],
+ mgmt_frame_len - DOT11_MGMT_HDR_LEN)) {
+ p2p_act_frm = (wifi_p2p_action_frame_t *)
+ (&mgmt_frame[DOT11_MGMT_HDR_LEN]);
+ (void) p2p_act_frm;
+ } else if (wl_cfgp2p_is_gas_action(&mgmt_frame[DOT11_MGMT_HDR_LEN],
+ mgmt_frame_len - DOT11_MGMT_HDR_LEN)) {
+ sd_act_frm = (wifi_p2psd_gas_pub_act_frame_t *)
+ (&mgmt_frame[DOT11_MGMT_HDR_LEN]);
+ (void) sd_act_frm;
+ }
+ wl_cfgp2p_print_actframe(false, &mgmt_frame[DOT11_MGMT_HDR_LEN],
+ mgmt_frame_len - DOT11_MGMT_HDR_LEN);
/*
* After complete GO Negotiation, roll back to mpc mode
*/
- if (act_frm->subtype == P2P_PAF_GON_CONF) {
- wldev_iovar_setint(ndev, "mpc", 1);
+ if (act_frm && ((act_frm->subtype == P2P_PAF_GON_CONF) ||
+ (act_frm->subtype == P2P_PAF_PROVDIS_RSP))) {
+ wldev_iovar_setint(dev, "mpc", 1);
}
} else {
mgmt_frame = (u8 *)((wl_event_rx_frame_data_t *)rxframe + 1);
@@ -4925,12 +5219,7 @@
static void wl_init_conf(struct wl_conf *conf)
{
- s32 i = 0;
WL_DBG(("Enter \n"));
- for (i = 0; i <= VWDEV_CNT; i++) {
- conf->mode[i].type = -1;
- conf->mode[i].ndev = NULL;
- }
conf->frag_threshold = (u32)-1;
conf->rts_threshold = (u32)-1;
conf->retry_short = (u32)-1;
@@ -4938,13 +5227,14 @@
conf->tx_power = -1;
}
-static void wl_init_prof(struct wl_priv *wl)
+static void wl_init_prof(struct wl_priv *wl, struct net_device *ndev)
{
unsigned long flags;
+ struct wl_profile *profile = wl_get_profile_by_netdev(wl, ndev);
- flags = dhd_os_spin_lock((dhd_pub_t *)(wl->pub));
- memset(wl->profile, 0, sizeof(struct wl_profile));
- dhd_os_spin_unlock((dhd_pub_t *)(wl->pub), flags);
+ spin_lock_irqsave(&wl->cfgdrv_lock, flags);
+ memset(profile, 0, sizeof(struct wl_profile));
+ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
}
static void wl_init_event_handler(struct wl_priv *wl)
@@ -4967,7 +5257,7 @@
wl->evt_handler[WLC_E_P2P_DISC_LISTEN_COMPLETE] = wl_cfgp2p_listen_complete;
wl->evt_handler[WLC_E_ACTION_FRAME_COMPLETE] = wl_cfgp2p_action_tx_complete;
wl->evt_handler[WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE] = wl_cfgp2p_action_tx_complete;
-
+ wl->evt_handler[WLC_E_PFN_NET_FOUND] = wl_notify_pfn_status;
}
static s32 wl_init_priv_mem(struct wl_priv *wl)
@@ -4983,23 +5273,13 @@
WL_ERR(("wl_conf alloc failed\n"));
goto init_priv_mem_out;
}
- wl->profile = (void *)kzalloc(sizeof(*wl->profile), GFP_KERNEL);
- if (unlikely(!wl->profile)) {
- WL_ERR(("wl_profile alloc failed\n"));
- goto init_priv_mem_out;
- }
- wl->bss_info = (void *)kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
- if (unlikely(!wl->bss_info)) {
- WL_ERR(("Bss information alloc failed\n"));
- goto init_priv_mem_out;
- }
wl->scan_req_int =
(void *)kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL);
if (unlikely(!wl->scan_req_int)) {
WL_ERR(("Scan req alloc failed\n"));
goto init_priv_mem_out;
}
- wl->ioctl_buf = (void *)kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
+ wl->ioctl_buf = (void *)kzalloc(WLC_IOCTL_MAXLEN, GFP_KERNEL);
if (unlikely(!wl->ioctl_buf)) {
WL_ERR(("Ioctl buf alloc failed\n"));
goto init_priv_mem_out;
@@ -5019,11 +5299,6 @@
WL_ERR(("Iscan buf alloc failed\n"));
goto init_priv_mem_out;
}
- wl->fw = (void *)kzalloc(sizeof(*wl->fw), GFP_KERNEL);
- if (unlikely(!wl->fw)) {
- WL_ERR(("fw object alloc failed\n"));
- goto init_priv_mem_out;
- }
wl->pmk_list = (void *)kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL);
if (unlikely(!wl->pmk_list)) {
WL_ERR(("pmk list alloc failed\n"));
@@ -5034,6 +5309,14 @@
WL_ERR(("sta info alloc failed\n"));
goto init_priv_mem_out;
}
+ wl->afx_hdl = (void *)kzalloc(sizeof(*wl->afx_hdl), GFP_KERNEL);
+ if (unlikely(!wl->afx_hdl)) {
+ WL_ERR(("afx hdl alloc failed\n"));
+ goto init_priv_mem_out;
+ } else {
+ init_completion(&wl->act_frm_scan);
+ INIT_WORK(&wl->afx_hdl->work, wl_cfg80211_afx_handler);
+ }
return 0;
init_priv_mem_out:
@@ -5046,12 +5329,8 @@
{
kfree(wl->scan_results);
wl->scan_results = NULL;
- kfree(wl->bss_info);
- wl->bss_info = NULL;
kfree(wl->conf);
wl->conf = NULL;
- kfree(wl->profile);
- wl->profile = NULL;
kfree(wl->scan_req_int);
wl->scan_req_int = NULL;
kfree(wl->ioctl_buf);
@@ -5062,12 +5341,16 @@
wl->extra_buf = NULL;
kfree(wl->iscan);
wl->iscan = NULL;
- kfree(wl->fw);
- wl->fw = NULL;
kfree(wl->pmk_list);
wl->pmk_list = NULL;
kfree(wl->sta_info);
wl->sta_info = NULL;
+ if (wl->afx_hdl) {
+ cancel_work_sync(&wl->afx_hdl->work);
+ kfree(wl->afx_hdl);
+ wl->afx_hdl = NULL;
+ }
+
if (wl->ap_info) {
kfree(wl->ap_info->wpa_ie);
kfree(wl->ap_info->rsn_ie);
@@ -5082,7 +5365,8 @@
int ret = 0;
WL_DBG(("Enter \n"));
- wl->event_tsk.thr_pid = DHD_PID_KT_INVALID;
+ /* Do not use DHD in cfg driver */
+ wl->event_tsk.thr_pid = -1;
PROC_START(wl_event_handler, wl, &wl->event_tsk, 0);
if (wl->event_tsk.thr_pid < 0)
ret = -ENOMEM;
@@ -5112,21 +5396,22 @@
static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted)
{
struct wl_priv *wl = iscan_to_wl(iscan);
+ struct net_device *ndev = wl_to_prmry_ndev(wl);
unsigned long flags;
WL_DBG(("Enter \n"));
- if (unlikely(!wl_get_drv_status(wl, SCANNING))) {
- wl_clr_drv_status(wl, SCANNING);
+ if (!wl_get_drv_status(wl, SCANNING, ndev)) {
+ wl_clr_drv_status(wl, SCANNING, ndev);
WL_ERR(("Scan complete while device not scanning\n"));
return;
}
- flags = dhd_os_spin_lock((dhd_pub_t *)(wl->pub));
- wl_clr_drv_status(wl, SCANNING);
+ spin_lock_irqsave(&wl->cfgdrv_lock, flags);
+ wl_clr_drv_status(wl, SCANNING, ndev);
if (likely(wl->scan_request)) {
cfg80211_scan_done(wl->scan_request, aborted);
wl->scan_request = NULL;
}
- dhd_os_spin_unlock((dhd_pub_t *)(wl->pub), flags);
+ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
wl->iscan_kickstart = false;
}
@@ -5162,7 +5447,7 @@
list.results.buflen = htod32(WL_ISCAN_BUF_MAX);
err = wldev_iovar_getbuf(iscan->dev, "iscanresults", &list,
WL_ISCAN_RESULTS_FIXED_SIZE, iscan->scan_buf,
- WL_ISCAN_BUF_MAX);
+ WL_ISCAN_BUF_MAX, NULL);
if (unlikely(err)) {
WL_ERR(("error (%d)\n", err));
return err;
@@ -5235,13 +5520,11 @@
static s32 wl_iscan_thread(void *data)
{
- struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
struct wl_priv *wl = iscan_to_wl(iscan);
u32 status;
int err = 0;
- sched_setscheduler(current, SCHED_FIFO, ¶m);
allow_signal(SIGTERM);
status = WL_SCAN_RESULTS_PARTIAL;
while (likely(!down_interruptible(&iscan->sync))) {
@@ -5276,7 +5559,7 @@
if (wl->scan_request) {
WL_ERR(("timer expired\n"));
if (wl->escan_on)
- wl_notify_escan_complete(wl, true);
+ wl_notify_escan_complete(wl, wl->escan_info.ndev, true);
else
wl_notify_iscan_complete(wl_to_iscan(wl), true);
}
@@ -5322,21 +5605,47 @@
iscan->iscan_handler[WL_SCAN_RESULTS_NO_MEM] = wl_iscan_aborted;
}
-static void wl_notify_escan_complete(struct wl_priv *wl, bool aborted)
+static s32
+wl_cfg80211_netdev_notifier_call(struct notifier_block * nb,
+ unsigned long state,
+ void *ndev)
+{
+ struct net_device *dev = ndev;
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct wl_priv *wl = wlcfg_drv_priv;
+
+ WL_DBG(("Enter \n"));
+ if (!wdev || dev == wl_to_prmry_ndev(wl))
+ return NOTIFY_DONE;
+ switch (state) {
+ case NETDEV_UNREGISTER:
+ /* after calling list_del_rcu(&wdev->list) */
+ wl_dealloc_netinfo(wl, ndev);
+ break;
+ }
+ return NOTIFY_DONE;
+}
+static struct notifier_block wl_cfg80211_netdev_notifier = {
+ .notifier_call = wl_cfg80211_netdev_notifier_call,
+};
+
+static void wl_notify_escan_complete(struct wl_priv *wl,
+ struct net_device *ndev,
+ bool aborted)
{
unsigned long flags;
WL_DBG(("Enter \n"));
- wl_clr_drv_status(wl, SCANNING);
- if (wl->p2p_supported && p2p_on(wl))
+ wl_clr_drv_status(wl, SCANNING, ndev);
+ if (p2p_is_on(wl))
wl_clr_p2p_status(wl, SCANNING);
- flags = dhd_os_spin_lock((dhd_pub_t *)(wl->pub));
+ spin_lock_irqsave(&wl->cfgdrv_lock, flags);
if (likely(wl->scan_request)) {
cfg80211_scan_done(wl->scan_request, aborted);
wl->scan_request = NULL;
}
- dhd_os_spin_unlock((dhd_pub_t *)(wl->pub), flags);
+ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
}
static s32 wl_escan_handler(struct wl_priv *wl,
@@ -5351,11 +5660,22 @@
wl_scan_results_t *list;
u32 bi_length;
u32 i;
+ u8 *p2p_dev_addr = NULL;
+
WL_DBG((" enter event type : %d, status : %d \n",
ntoh32(e->event_type), ntoh32(e->status)));
- if (!wl->escan_on &&
- !wl_get_drv_status(wl, SCANNING)) {
- WL_ERR(("escan is not ready \n"));
+ /* P2P SCAN is coming from primary interface */
+ if (wl_get_p2p_status(wl, SCANNING)) {
+ if (wl_get_drv_status_all(wl, SENDING_ACT_FRM))
+ ndev = wl->afx_hdl->dev;
+ else
+ ndev = wl->escan_info.ndev;
+
+ }
+ if (!ndev || !wl->escan_on ||
+ !wl_get_drv_status(wl, SCANNING, ndev)) {
+ WL_ERR(("escan is not ready ndev %p wl->escan_on %d drv_status 0x%x\n",
+ ndev, wl->escan_on, wl_get_drv_status(wl, SCANNING, ndev)));
return err;
}
@@ -5380,77 +5700,118 @@
WL_ERR(("Invalid bss_info length %d: ignoring\n", bi_length));
goto exit;
}
- list = (wl_scan_results_t *)wl->escan_info.escan_buf;
- if (bi_length > ESCAN_BUF_SIZE - list->buflen) {
- WL_ERR(("Buffer is too small: ignoring\n"));
- goto exit;
- }
-#define WLC_BSS_RSSI_ON_CHANNEL 0x0002
- for (i = 0; i < list->count; i++) {
- bss = bss ? (wl_bss_info_t *)((uintptr)bss + dtoh32(bss->length))
- : list->bss_info;
- if (!bcmp(&bi->BSSID, &bss->BSSID, ETHER_ADDR_LEN) &&
- CHSPEC_BAND(bi->chanspec) == CHSPEC_BAND(bss->chanspec) &&
- bi->SSID_len == bss->SSID_len &&
- !bcmp(bi->SSID, bss->SSID, bi->SSID_len)) {
- if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) ==
- (bi->flags & WLC_BSS_RSSI_ON_CHANNEL)) {
- /* preserve max RSSI if the measurements are
- * both on-channel or both off-channel
- */
- bss->RSSI = MAX(bss->RSSI, bi->RSSI);
- } else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) &&
- (bi->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) {
- /* preserve the on-channel rssi measurement
- * if the new measurement is off channel
- */
- bss->RSSI = bi->RSSI;
- bss->flags |= WLC_BSS_RSSI_ON_CHANNEL;
- }
-
+ if (!(wl_to_wiphy(wl)->interface_modes & BIT(NL80211_IFTYPE_ADHOC))) {
+ if (dtoh16(bi->capability) & DOT11_CAP_IBSS) {
+ WL_ERR(("Ignoring IBSS result\n"));
goto exit;
}
}
- memcpy(&(wl->escan_info.escan_buf[list->buflen]), bi, bi_length);
- list->version = dtoh32(bi->version);
- list->buflen += bi_length;
- list->count++;
+
+ if (wl_get_drv_status_all(wl, SENDING_ACT_FRM)) {
+ p2p_dev_addr = wl_cfgp2p_retreive_p2p_dev_addr(bi, bi_length);
+ if (p2p_dev_addr && !memcmp(p2p_dev_addr,
+ wl->afx_hdl->pending_tx_dst_addr.octet, ETHER_ADDR_LEN)) {
+ s32 channel = CHSPEC_CHANNEL(dtohchanspec(bi->chanspec));
+ WL_DBG(("ACTION FRAME SCAN : Peer found, channel : %d\n", channel));
+ wl_clr_p2p_status(wl, SCANNING);
+ wl->afx_hdl->peer_chan = channel;
+ complete(&wl->act_frm_scan);
+ goto exit;
+ }
+
+ } else {
+ list = (wl_scan_results_t *)wl->escan_info.escan_buf;
+ if (bi_length > ESCAN_BUF_SIZE - list->buflen) {
+ WL_ERR(("Buffer is too small: ignoring\n"));
+ goto exit;
+ }
+#define WLC_BSS_RSSI_ON_CHANNEL 0x0002
+ for (i = 0; i < list->count; i++) {
+ bss = bss ? (wl_bss_info_t *)((uintptr)bss + dtoh32(bss->length))
+ : list->bss_info;
+
+ if (!bcmp(&bi->BSSID, &bss->BSSID, ETHER_ADDR_LEN) &&
+ CHSPEC_BAND(bi->chanspec) == CHSPEC_BAND(bss->chanspec) &&
+ bi->SSID_len == bss->SSID_len &&
+ !bcmp(bi->SSID, bss->SSID, bi->SSID_len)) {
+ if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) ==
+ (bi->flags & WLC_BSS_RSSI_ON_CHANNEL)) {
+ /* preserve max RSSI if the measurements are
+ * both on-channel or both off-channel
+ */
+ bss->RSSI = MAX(bss->RSSI, bi->RSSI);
+ } else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) &&
+ (bi->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) {
+ /* preserve the on-channel rssi measurement
+ * if the new measurement is off channel
+ */
+ bss->RSSI = bi->RSSI;
+ bss->flags |= WLC_BSS_RSSI_ON_CHANNEL;
+ }
+
+ goto exit;
+ }
+ }
+ memcpy(&(wl->escan_info.escan_buf[list->buflen]), bi, bi_length);
+ list->version = dtoh32(bi->version);
+ list->buflen += bi_length;
+ list->count++;
+
+ }
}
else if (status == WLC_E_STATUS_SUCCESS) {
wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
- if (likely(wl->scan_request)) {
+ if (wl_get_drv_status_all(wl, SENDING_ACT_FRM)) {
+ WL_INFO(("ACTION FRAME SCAN DONE\n"));
+ wl_clr_p2p_status(wl, SCANNING);
+ wl_clr_drv_status(wl, SCANNING, wl->afx_hdl->dev);
+ if (wl->afx_hdl->peer_chan == WL_INVALID)
+ complete(&wl->act_frm_scan);
+ } else if (likely(wl->scan_request)) {
mutex_lock(&wl->usr_sync);
del_timer_sync(&wl->scan_timeout);
WL_INFO(("ESCAN COMPLETED\n"));
wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf;
wl_inform_bss(wl);
- wl_notify_escan_complete(wl, false);
+ wl_notify_escan_complete(wl, ndev, false);
mutex_unlock(&wl->usr_sync);
}
}
else if (status == WLC_E_STATUS_ABORT) {
wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
- if (likely(wl->scan_request)) {
+ if (wl_get_drv_status_all(wl, SENDING_ACT_FRM)) {
+ WL_INFO(("ACTION FRAME SCAN DONE\n"));
+ wl_clr_drv_status(wl, SCANNING, wl->afx_hdl->dev);
+ wl_clr_p2p_status(wl, SCANNING);
+ if (wl->afx_hdl->peer_chan == WL_INVALID)
+ complete(&wl->act_frm_scan);
+ } else if (likely(wl->scan_request)) {
mutex_lock(&wl->usr_sync);
del_timer_sync(&wl->scan_timeout);
WL_INFO(("ESCAN ABORTED\n"));
wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf;
wl_inform_bss(wl);
- wl_notify_escan_complete(wl, true);
+ wl_notify_escan_complete(wl, ndev, true);
mutex_unlock(&wl->usr_sync);
}
}
else {
WL_ERR(("unexpected Escan Event %d : abort\n", status));
wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
- if (likely(wl->scan_request)) {
+ if (wl_get_drv_status_all(wl, SENDING_ACT_FRM)) {
+ WL_INFO(("ACTION FRAME SCAN DONE\n"));
+ wl_clr_p2p_status(wl, SCANNING);
+ wl_clr_drv_status(wl, SCANNING, wl->afx_hdl->dev);
+ if (wl->afx_hdl->peer_chan == WL_INVALID)
+ complete(&wl->act_frm_scan);
+ } else if (likely(wl->scan_request)) {
mutex_lock(&wl->usr_sync);
del_timer_sync(&wl->scan_timeout);
wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf;
wl_inform_bss(wl);
- wl_notify_escan_complete(wl, true);
+ wl_notify_escan_complete(wl, ndev, true);
mutex_unlock(&wl->usr_sync);
}
}
@@ -5491,16 +5852,11 @@
return err;
}
-static void wl_init_fw(struct wl_fw_ctrl *fw)
-{
- fw->status = 0;
-}
-
static s32 wl_init_priv(struct wl_priv *wl)
{
struct wiphy *wiphy = wl_to_wiphy(wl);
+ struct net_device *ndev = wl_to_prmry_ndev(wl);
s32 err = 0;
- s32 i = 0;
wl->scan_request = NULL;
wl->pwr_save = !!(wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT);
@@ -5509,60 +5865,77 @@
wl->roam_on = false;
wl->iscan_kickstart = false;
wl->active_scan = true;
- wl->dongle_up = false;
wl->rf_blocked = false;
-
- for (i = 0; i < VWDEV_CNT; i++)
- wl->vwdev[i] = NULL;
-
- init_waitqueue_head(&wl->dongle_event_wait);
+ spin_lock_init(&wl->cfgdrv_lock);
+ mutex_init(&wl->ioctl_buf_sync);
+ init_waitqueue_head(&wl->netif_change_event);
wl_init_eq(wl);
err = wl_init_priv_mem(wl);
- if (unlikely(err))
+ if (err)
return err;
- if (unlikely(wl_create_event_handler(wl)))
+ if (wl_create_event_handler(wl))
return -ENOMEM;
wl_init_event_handler(wl);
mutex_init(&wl->usr_sync);
err = wl_init_scan(wl);
- if (unlikely(err))
+ if (err)
return err;
- wl_init_fw(wl->fw);
wl_init_conf(wl->conf);
- wl_init_prof(wl);
+ wl_init_prof(wl, ndev);
wl_link_down(wl);
+ DNGL_FUNC(dhd_cfg80211_init, (wl));
return err;
}
static void wl_deinit_priv(struct wl_priv *wl)
{
+ DNGL_FUNC(dhd_cfg80211_deinit, (wl));
wl_destroy_event_handler(wl);
- wl->dongle_up = false; /* dongle down */
wl_flush_eq(wl);
wl_link_down(wl);
del_timer_sync(&wl->scan_timeout);
wl_term_iscan(wl);
wl_deinit_priv_mem(wl);
+ unregister_netdevice_notifier(&wl_cfg80211_netdev_notifier);
}
-#if defined(DHD_P2P_DEV_ADDR_FROM_SYSFS) && defined(CONFIG_SYSCTL)
-s32 wl_cfg80211_sysctl_export_devaddr(void *data)
+#if defined(WLP2P) && ENABLE_P2P_INTERFACE
+static s32 wl_cfg80211_attach_p2p(void)
{
- /* Export the p2p_dev_addr via sysctl interface
- * so that wpa_supplicant can access it
- */
- dhd_pub_t *dhd = (dhd_pub_t *)data;
struct wl_priv *wl = wlcfg_drv_priv;
- wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p->dev_addr, &wl->p2p->int_addr);
+ WL_TRACE(("Enter \n"));
- sprintf((char *)&wl_sysctl_macstring[0], MACSTR, MAC2STR(wl->p2p->dev_addr.octet));
- sprintf((char *)&wl_sysctl_macstring[1], MACSTR, MAC2STR(wl->p2p->int_addr.octet));
+ if (wl_cfgp2p_register_ndev(wl) < 0) {
+ WL_ERR(("%s: P2P attach failed. \n", __func__));
+ return -ENODEV;
+ }
return 0;
}
-#endif /* CONFIG_SYSCTL */
+
+static s32 wl_cfg80211_detach_p2p(void)
+{
+ struct wl_priv *wl = wlcfg_drv_priv;
+ struct wireless_dev *wdev = wl->p2p_wdev;
+
+ WL_DBG(("Enter \n"));
+ if (!wdev || !wl) {
+ WL_ERR(("Invalid Ptr\n"));
+ return -EINVAL;
+ }
+
+ wl_cfgp2p_unregister_ndev(wl);
+
+ wl->p2p_wdev = NULL;
+ wl->p2p_net = NULL;
+ WL_DBG(("Freeing 0x%08x \n", (unsigned int)wdev));
+ kfree(wdev);
+
+ return 0;
+}
+#endif /* defined(WLP2P) && (ENABLE_P2P_INTERFACE) */
s32 wl_cfg80211_attach_post(struct net_device *ndev)
{
@@ -5574,75 +5947,107 @@
return -ENODEV;
}
wl = wlcfg_drv_priv;
- if (wl && !wl_get_drv_status(wl, READY)) {
+ if (wl && !wl_get_drv_status(wl, READY, ndev)) {
if (wl->wdev &&
wl_cfgp2p_supported(wl, ndev)) {
+#if !ENABLE_P2P_INTERFACE
wl->wdev->wiphy->interface_modes |=
(BIT(NL80211_IFTYPE_P2P_CLIENT)|
BIT(NL80211_IFTYPE_P2P_GO));
+#endif
if ((err = wl_cfgp2p_init_priv(wl)) != 0)
goto fail;
-#if defined(DHD_P2P_DEV_ADDR_FROM_SYSFS) && defined(CONFIG_SYSCTL)
- wl_cfg80211_sysctl_export_devaddr(wl->pub);
-#endif
+
+#if defined(WLP2P) && ENABLE_P2P_INTERFACE
+ if (wl->p2p_net) {
+ /* Update MAC addr for p2p0 interface here. */
+ memcpy(wl->p2p_net->dev_addr, ndev->dev_addr, ETH_ALEN);
+ wl->p2p_net->dev_addr[0] |= 0x02;
+ printk("%s: p2p_dev_addr="MACSTR "\n",
+ wl->p2p_net->name, MAC2STR(wl->p2p_net->dev_addr));
+ } else {
+ WL_ERR(("p2p_net not yet populated."
+ " Couldn't update the MAC Address for p2p0 \n"));
+ return -ENODEV;
+ }
+#endif /* defined(WLP2P) && (ENABLE_P2P_INTERFACE) */
+
wl->p2p_supported = true;
}
} else
return -ENODEV;
-
- wl_set_drv_status(wl, READY);
+ wl_set_drv_status(wl, READY, ndev);
fail:
return err;
}
+
s32 wl_cfg80211_attach(struct net_device *ndev, void *data)
{
struct wireless_dev *wdev;
struct wl_priv *wl;
s32 err = 0;
+ struct device *dev;
WL_TRACE(("In\n"));
- if (unlikely(!ndev)) {
+ if (!ndev) {
WL_ERR(("ndev is invaild\n"));
return -ENODEV;
}
- WL_DBG(("func %p\n", wl_cfg80211_get_sdio_func()));
- wdev = wl_alloc_wdev(&wl_cfg80211_get_sdio_func()->dev);
- if (unlikely(IS_ERR(wdev)))
- return -ENOMEM;
+ WL_DBG(("func %p\n", wl_cfg80211_get_parent_dev()));
+ dev = wl_cfg80211_get_parent_dev();
+ wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
+ if (unlikely(!wdev)) {
+ WL_ERR(("Could not allocate wireless device\n"));
+ return -ENOMEM;
+ }
+ err = wl_setup_wiphy(wdev, dev);
+ if (unlikely(err)) {
+ kfree(wdev);
+ return -ENOMEM;
+ }
wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS);
wl = (struct wl_priv *)wiphy_priv(wdev->wiphy);
wl->wdev = wdev;
wl->pub = data;
-
+ INIT_LIST_HEAD(&wl->net_list);
ndev->ieee80211_ptr = wdev;
SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
wdev->netdev = ndev;
-
+ err = wl_alloc_netinfo(wl, ndev, wdev, WL_MODE_BSS);
+ if (err) {
+ WL_ERR(("Failed to alloc net_info (%d)\n", err));
+ goto cfg80211_attach_out;
+ }
err = wl_init_priv(wl);
- if (unlikely(err)) {
+ if (err) {
WL_ERR(("Failed to init iwm_priv (%d)\n", err));
goto cfg80211_attach_out;
}
err = wl_setup_rfkill(wl, TRUE);
- if (unlikely(err)) {
+ if (err) {
WL_ERR(("Failed to setup rfkill %d\n", err));
goto cfg80211_attach_out;
}
-
-#if defined(DHD_P2P_DEV_ADDR_FROM_SYSFS) && defined(CONFIG_SYSCTL)
- if (!(wl_sysctl_hdr = register_sysctl_table(wl_sysctl_table))) {
- WL_ERR(("%s: sysctl register failed!! \n", __func__));
+ err = register_netdevice_notifier(&wl_cfg80211_netdev_notifier);
+ if (err) {
+ WL_ERR(("Failed to register notifierl %d\n", err));
goto cfg80211_attach_out;
}
-#endif
#if defined(COEX_DHCP)
if (wl_cfg80211_btcoex_init(wl))
goto cfg80211_attach_out;
-#endif /* COEX_DHCP */
+#endif
wlcfg_drv_priv = wl;
+
+#if defined(WLP2P) && ENABLE_P2P_INTERFACE
+ err = wl_cfg80211_attach_p2p();
+ if (err)
+ goto cfg80211_attach_out;
+#endif
+
return err;
cfg80211_attach_out:
@@ -5651,7 +6056,7 @@
return err;
}
-void wl_cfg80211_detach(void)
+void wl_cfg80211_detach(void *para)
{
struct wl_priv *wl;
@@ -5661,19 +6066,21 @@
#if defined(COEX_DHCP)
wl_cfg80211_btcoex_deinit(wl);
-#endif /* COEX_DHCP */
+#endif
-#if defined(DHD_P2P_DEV_ADDR_FROM_SYSFS) && defined(CONFIG_SYSCTL)
- if (wl_sysctl_hdr)
- unregister_sysctl_table(wl_sysctl_hdr);
+#if defined(WLP2P) && ENABLE_P2P_INTERFACE
+ wl_cfg80211_detach_p2p();
#endif
wl_setup_rfkill(wl, FALSE);
if (wl->p2p_supported)
wl_cfgp2p_deinit_priv(wl);
wl_deinit_priv(wl);
wlcfg_drv_priv = NULL;
- wl_clear_sdio_func();
+ wl_cfg80211_clear_parent_dev();
wl_free_wdev(wl);
+ /* PLEASE do NOT call any function after wl_free_wdev, the driver's private structure "wl",
+ * which is the private part of wiphy, has been freed in wl_free_wdev !!!!!!!!!!!
+ */
}
static void wl_wakeup_event(struct wl_priv *wl)
@@ -5684,6 +6091,42 @@
}
}
+static int wl_is_p2p_event(struct wl_event_q *e)
+{
+ switch (e->etype) {
+ /* We have to seperate out the P2P events received
+ * on primary interface so that it can be send up
+ * via p2p0 interface.
+ */
+ case WLC_E_P2P_PROBREQ_MSG:
+ case WLC_E_P2P_DISC_LISTEN_COMPLETE:
+ case WLC_E_ACTION_FRAME_RX:
+ case WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE:
+ case WLC_E_ACTION_FRAME_COMPLETE:
+
+ if (e->emsg.ifidx != 0) {
+ WL_TRACE(("P2P Event on Virtual I/F (ifidx:%d) \n",
+ e->emsg.ifidx));
+ /* We are only bothered about the P2P events received
+ * on primary interface. For rest of them return false
+ * so that it is sent over the interface corresponding
+ * to the ifidx.
+ */
+ return FALSE;
+ } else {
+ WL_TRACE(("P2P Event on Primary I/F (ifidx:%d)."
+ " Sent it to p2p0 \n", e->emsg.ifidx));
+ return TRUE;
+ }
+ break;
+
+ default:
+ WL_TRACE(("NON-P2P Event %d on ifidx (ifidx:%d) \n",
+ e->etype, e->emsg.ifidx));
+ return FALSE;
+ }
+}
+
static s32 wl_event_handler(void *data)
{
struct net_device *netdev;
@@ -5692,6 +6135,9 @@
tsk_ctl_t *tsk = (tsk_ctl_t *)data;
wl = (struct wl_priv *)tsk->parent;
+
+ DAEMONIZE("wl_event_handler");
+
complete(&tsk->completed);
while (down_interruptible (&tsk->sema) == 0) {
@@ -5700,7 +6146,15 @@
break;
while ((e = wl_deq_event(wl))) {
WL_DBG(("event type (%d), if idx: %d\n", e->etype, e->emsg.ifidx));
- netdev = dhd_idx2net((struct dhd_pub *)(wl->pub), e->emsg.ifidx);
+ /* All P2P device address related events comes on primary interface since
+ * there is no corresponding bsscfg for P2P interface. Map it to p2p0
+ * interface.
+ */
+ if ((wl_is_p2p_event(e) == TRUE) && (wl->p2p_net)) {
+ netdev = wl->p2p_net;
+ } else {
+ netdev = dhd_idx2net((struct dhd_pub *)(wl->pub), e->emsg.ifidx);
+ }
if (!netdev)
netdev = wl_to_prmry_ndev(wl);
if (e->etype < WLC_E_LAST && wl->evt_handler[e->etype]) {
@@ -5729,9 +6183,6 @@
WL_DBG(("event_type (%d):" "WLC_E_" "%s\n", event_type, estr));
#endif /* (WL_DBG_LEVEL > 0) */
- if (event_type == WLC_E_PFN_NET_FOUND)
- WL_ERR((" PNO Event\n"));
-
if (likely(!wl_enq_event(wl, ndev, event_type, e, data)))
wl_wakeup_event(wl);
}
@@ -5816,22 +6267,7 @@
kfree(e);
}
-void wl_cfg80211_set_sdio_func(void *func)
-{
- cfg80211_sdio_func = (struct sdio_func *)func;
-}
-
-static void wl_clear_sdio_func(void)
-{
- cfg80211_sdio_func = NULL;
-}
-
-struct sdio_func *wl_cfg80211_get_sdio_func(void)
-{
- return cfg80211_sdio_func;
-}
-
-static s32 wl_dongle_mode(struct wl_priv *wl, struct net_device *ndev, s32 iftype)
+static s32 wl_config_ifmode(struct wl_priv *wl, struct net_device *ndev, s32 iftype)
{
s32 infra = 0;
s32 err = 0;
@@ -5868,11 +6304,12 @@
return err;
}
- set_mode_by_netdev(wl, ndev, mode);
+ wl_set_mode_by_netdev(wl, ndev, mode);
return 0;
}
-static s32 wl_dongle_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add)
+
+static s32 wl_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add)
{
s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
@@ -5885,7 +6322,7 @@
err = wldev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf), false);
if (unlikely(err)) {
WL_ERR(("Get event_msgs error (%d)\n", err));
- goto dongle_eventmsg_out;
+ goto eventmsg_out;
}
memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN);
if (add) {
@@ -5898,353 +6335,15 @@
err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), true);
if (unlikely(err)) {
WL_ERR(("Set event_msgs error (%d)\n", err));
- goto dongle_eventmsg_out;
+ goto eventmsg_out;
}
-dongle_eventmsg_out:
+eventmsg_out:
return err;
}
-
-#ifndef EMBEDDED_PLATFORM
-static s32 wl_dongle_country(struct net_device *ndev, u8 ccode)
-{
-
- s32 err = 0;
-
- return err;
-}
-
-static s32 wl_dongle_up(struct net_device *ndev, u32 up)
-{
- s32 err = 0;
-
- err = wldev_ioctl(ndev, WLC_UP, &up, sizeof(up), true);
- if (unlikely(err)) {
- WL_ERR(("WLC_UP error (%d)\n", err));
- }
- return err;
-}
-
-static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode)
-{
- s32 err = 0;
-
- WL_TRACE(("In\n"));
- err = wldev_ioctl(ndev, WLC_SET_PM, &power_mode, sizeof(power_mode), true);
- if (unlikely(err)) {
- WL_ERR(("WLC_SET_PM error (%d)\n", err));
- }
- return err;
-}
-
-static s32
-wl_dongle_glom(struct net_device *ndev, u32 glom, u32 dongle_align)
-{
- s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
-
- s32 err = 0;
-
- /* Match Host and Dongle rx alignment */
- bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf,
- sizeof(iovbuf));
- err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), true);
- if (unlikely(err)) {
- WL_ERR(("txglomalign error (%d)\n", err));
- goto dongle_glom_out;
- }
- /* disable glom option per default */
- bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
- err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), true);
- if (unlikely(err)) {
- WL_ERR(("txglom error (%d)\n", err));
- goto dongle_glom_out;
- }
-dongle_glom_out:
- return err;
-}
-
-static s32
-wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
-{
- s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
-
- s32 err = 0;
-
- /* Setup timeout if Beacons are lost and roam is off to report link down */
- if (roamvar) {
- bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
- sizeof(iovbuf));
- err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), true);
- if (unlikely(err)) {
- WL_ERR(("bcn_timeout error (%d)\n", err));
- goto dongle_rom_out;
- }
- }
- /* Enable/Disable built-in roaming to allow supplicant to take care of roaming */
- bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf));
- err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), true);
- if (unlikely(err)) {
- WL_ERR(("roam_off error (%d)\n", err));
- goto dongle_rom_out;
- }
-dongle_rom_out:
- return err;
-}
-
-static s32
-wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
- s32 scan_unassoc_time)
-{
- s32 err = 0;
-
- err = wldev_ioctl(ndev, WLC_SET_SCAN_CHANNEL_TIME, &scan_assoc_time,
- sizeof(scan_assoc_time), true);
- if (err) {
- if (err == -EOPNOTSUPP) {
- WL_INFO(("Scan assoc time is not supported\n"));
- } else {
- WL_ERR(("Scan assoc time error (%d)\n", err));
- }
- goto dongle_scantime_out;
- }
- err = wldev_ioctl(ndev, WLC_SET_SCAN_UNASSOC_TIME, &scan_unassoc_time,
- sizeof(scan_unassoc_time), true);
- if (err) {
- if (err == -EOPNOTSUPP) {
- WL_INFO(("Scan unassoc time is not supported\n"));
- } else {
- WL_ERR(("Scan unassoc time error (%d)\n", err));
- }
- goto dongle_scantime_out;
- }
-
-dongle_scantime_out:
- return err;
-}
-
-static s32
-wl_dongle_offload(struct net_device *ndev, s32 arpoe, s32 arp_ol)
-{
- /* Room for "event_msgs" + '\0' + bitvec */
- s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
-
- s32 err = 0;
-
- /* Set ARP offload */
- bcm_mkiovar("arpoe", (char *)&arpoe, 4, iovbuf, sizeof(iovbuf));
- err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), true);
- if (err) {
- if (err == -EOPNOTSUPP)
- WL_INFO(("arpoe is not supported\n"));
- else
- WL_ERR(("arpoe error (%d)\n", err));
-
- goto dongle_offload_out;
- }
- bcm_mkiovar("arp_ol", (char *)&arp_ol, 4, iovbuf, sizeof(iovbuf));
- err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), true);
- if (err) {
- if (err == -EOPNOTSUPP)
- WL_INFO(("arp_ol is not supported\n"));
- else
- WL_ERR(("arp_ol error (%d)\n", err));
-
- goto dongle_offload_out;
- }
-
-dongle_offload_out:
- return err;
-}
-
-static s32 wl_pattern_atoh(s8 *src, s8 *dst)
-{
- int i;
- if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) {
- WL_ERR(("Mask invalid format. Needs to start with 0x\n"));
- return -1;
- }
- src = src + 2; /* Skip past 0x */
- if (strlen(src) % 2 != 0) {
- WL_ERR(("Mask invalid format. Needs to be of even length\n"));
- return -1;
- }
- for (i = 0; *src != '\0'; i++) {
- char num[3];
- strncpy(num, src, 2);
- num[2] = '\0';
- dst[i] = (u8) simple_strtoul(num, NULL, 16);
- src += 2;
- }
- return i;
-}
-
-static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode)
-{
- /* Room for "event_msgs" + '\0' + bitvec */
- s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
-
- const s8 *str;
- struct wl_pkt_filter pkt_filter;
- struct wl_pkt_filter *pkt_filterp;
- s32 buf_len;
- s32 str_len;
- u32 mask_size;
- u32 pattern_size;
- s8 buf[256];
- s32 err = 0;
-
- /* add a default packet filter pattern */
- str = "pkt_filter_add";
- str_len = strlen(str);
- strncpy(buf, str, str_len);
- buf[str_len] = '\0';
- buf_len = str_len + 1;
-
- pkt_filterp = (struct wl_pkt_filter *)(buf + str_len + 1);
-
- /* Parse packet filter id. */
- pkt_filter.id = htod32(100);
-
- /* Parse filter polarity. */
- pkt_filter.negate_match = htod32(0);
-
- /* Parse filter type. */
- pkt_filter.type = htod32(0);
-
- /* Parse pattern filter offset. */
- pkt_filter.u.pattern.offset = htod32(0);
-
- /* Parse pattern filter mask. */
- mask_size = htod32(wl_pattern_atoh("0xff",
- (char *)pkt_filterp->u.pattern.
- mask_and_pattern));
-
- /* Parse pattern filter pattern. */
- pattern_size = htod32(wl_pattern_atoh("0x00",
- (char *)&pkt_filterp->u.pattern.mask_and_pattern[mask_size]));
-
- if (mask_size != pattern_size) {
- WL_ERR(("Mask and pattern not the same size\n"));
- err = -EINVAL;
- goto dongle_filter_out;
- }
-
- pkt_filter.u.pattern.size_bytes = mask_size;
- buf_len += WL_PKT_FILTER_FIXED_LEN;
- buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
-
- /* Keep-alive attributes are set in local
- * variable (keep_alive_pkt), and
- * then memcpy'ed into buffer (keep_alive_pktp) since there is no
- * guarantee that the buffer is properly aligned.
- */
- memcpy((char *)pkt_filterp, &pkt_filter,
- WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN);
-
- err = wldev_ioctl(ndev, WLC_SET_VAR, buf, buf_len, true);
- if (err) {
- if (err == -EOPNOTSUPP) {
- WL_INFO(("filter not supported\n"));
- } else {
- WL_ERR(("filter (%d)\n", err));
- }
- goto dongle_filter_out;
- }
-
- /* set mode to allow pattern */
- bcm_mkiovar("pkt_filter_mode", (char *)&filter_mode, 4, iovbuf,
- sizeof(iovbuf));
- err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), true);
- if (err) {
- if (err == -EOPNOTSUPP) {
- WL_INFO(("filter_mode not supported\n"));
- } else {
- WL_ERR(("filter_mode (%d)\n", err));
- }
- goto dongle_filter_out;
- }
-
-dongle_filter_out:
- return err;
-}
-#endif /* !EMBEDDED_PLATFORM */
-
-s32 wl_config_dongle(struct wl_priv *wl, bool need_lock)
-{
-#ifndef DHD_SDALIGN
-#define DHD_SDALIGN 32
-#endif
- struct net_device *ndev;
- struct wireless_dev *wdev;
- s32 err = 0;
-
- WL_TRACE(("In\n"));
- if (wl->dongle_up) {
- WL_ERR(("Dongle is already up\n"));
- return err;
- }
-
- ndev = wl_to_prmry_ndev(wl);
- wdev = ndev->ieee80211_ptr;
- if (need_lock)
- rtnl_lock();
-#ifndef EMBEDDED_PLATFORM
- err = wl_dongle_up(ndev, 0);
- if (unlikely(err)) {
- WL_ERR(("wl_dongle_up failed\n"));
- goto default_conf_out;
- }
- err = wl_dongle_country(ndev, 0);
- if (unlikely(err)) {
- WL_ERR(("wl_dongle_country failed\n"));
- goto default_conf_out;
- }
- err = wl_dongle_power(ndev, PM_FAST);
- if (unlikely(err)) {
- WL_ERR(("wl_dongle_power failed\n"));
- goto default_conf_out;
- }
- err = wl_dongle_glom(ndev, 0, DHD_SDALIGN);
- if (unlikely(err)) {
- WL_ERR(("wl_dongle_glom failed\n"));
- goto default_conf_out;
- }
- err = wl_dongle_roam(ndev, (wl->roam_on ? 0 : 1), 3);
- if (unlikely(err)) {
- WL_ERR(("wl_dongle_roam failed\n"));
- goto default_conf_out;
- }
- wl_dongle_scantime(ndev, 40, 80);
- wl_dongle_offload(ndev, 1, 0xf);
- wl_dongle_filter(ndev, 1);
-#endif /* !EMBEDDED_PLATFORM */
-
- err = wl_dongle_mode(wl, ndev, wdev->iftype);
- if (unlikely(err && err != -EINPROGRESS)) {
- WL_ERR(("wl_dongle_mode failed\n"));
- goto default_conf_out;
- }
- err = wl_dongle_probecap(wl);
- if (unlikely(err)) {
- WL_ERR(("wl_dongle_probecap failed\n"));
- goto default_conf_out;
- }
-
- /* -EINPROGRESS: Call commit handler */
-
-default_conf_out:
- if (need_lock)
- rtnl_unlock();
-
- wl->dongle_up = true;
-
- return err;
-
-}
-
-static s32 wl_update_wiphybands(struct wl_priv *wl)
+s32 wl_update_wiphybands(struct wl_priv *wl)
{
struct wiphy *wiphy;
s8 phylist_buf[128];
@@ -6271,16 +6370,27 @@
static s32 __wl_cfg80211_up(struct wl_priv *wl)
{
s32 err = 0;
+ struct net_device *ndev = wl_to_prmry_ndev(wl);
+ struct wireless_dev *wdev = ndev->ieee80211_ptr;
WL_TRACE(("In\n"));
- wl_debugfs_add_netdev_params(wl);
- err = wl_config_dongle(wl, false);
+ err = dhd_config_dongle(wl, false);
if (unlikely(err))
return err;
- dhd_monitor_init(wl->pub);
- wl_invoke_iscan(wl);
- wl_set_drv_status(wl, READY);
+
+ err = wl_config_ifmode(wl, ndev, wdev->iftype);
+ if (unlikely(err && err != -EINPROGRESS)) {
+ WL_ERR(("wl_config_ifmode failed\n"));
+ }
+ err = wl_update_wiphybands(wl);
+ if (unlikely(err)) {
+ WL_ERR(("wl_update_wiphybands failed\n"));
+ }
+
+ err = dhd_monitor_init(wl->pub);
+ err = wl_invoke_iscan(wl);
+ wl_set_drv_status(wl, READY, ndev);
return err;
}
@@ -6288,47 +6398,47 @@
{
s32 err = 0;
unsigned long flags;
+ struct net_info *iter, *next;
+ struct net_device *ndev = wl_to_prmry_ndev(wl);
WL_TRACE(("In\n"));
/* Check if cfg80211 interface is already down */
- if (!wl_get_drv_status(wl, READY))
+ if (!wl_get_drv_status(wl, READY, ndev))
return err; /* it is even not ready */
-
- wl_set_drv_status(wl, SCAN_ABORTING);
+ for_each_ndev(wl, iter, next)
+ wl_set_drv_status(wl, SCAN_ABORTING, iter->ndev);
wl_term_iscan(wl);
- flags = dhd_os_spin_lock((dhd_pub_t *)(wl->pub));
+ spin_lock_irqsave(&wl->cfgdrv_lock, flags);
if (wl->scan_request) {
cfg80211_scan_done(wl->scan_request, true);
wl->scan_request = NULL;
}
- wl_clr_drv_status(wl, READY);
- wl_clr_drv_status(wl, SCANNING);
- wl_clr_drv_status(wl, SCAN_ABORTING);
- wl_clr_drv_status(wl, CONNECTING);
- wl_clr_drv_status(wl, CONNECTED);
- wl_clr_drv_status(wl, DISCONNECTING);
- if (wl_get_drv_status(wl, AP_CREATED)) {
- wl_clr_drv_status(wl, AP_CREATED);
- wl_clr_drv_status(wl, AP_CREATING);
+ for_each_ndev(wl, iter, next) {
+ wl_clr_drv_status(wl, READY, iter->ndev);
+ wl_clr_drv_status(wl, SCANNING, iter->ndev);
+ wl_clr_drv_status(wl, SCAN_ABORTING, iter->ndev);
+ wl_clr_drv_status(wl, CONNECTING, iter->ndev);
+ wl_clr_drv_status(wl, CONNECTED, iter->ndev);
+ wl_clr_drv_status(wl, DISCONNECTING, iter->ndev);
+ wl_clr_drv_status(wl, AP_CREATED, iter->ndev);
+ wl_clr_drv_status(wl, AP_CREATING, iter->ndev);
}
wl_to_prmry_ndev(wl)->ieee80211_ptr->iftype =
NL80211_IFTYPE_STATION;
- dhd_os_spin_unlock((dhd_pub_t *)(wl->pub), flags);
+ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
- wl->dongle_up = false;
+ DNGL_FUNC(dhd_cfg80211_down, (wl));
wl_flush_eq(wl);
wl_link_down(wl);
if (wl->p2p_supported)
wl_cfgp2p_down(wl);
dhd_monitor_uninit();
- wl_debugfs_remove_netdev(wl);
-
return err;
}
-s32 wl_cfg80211_up(void)
+s32 wl_cfg80211_up(void *para)
{
struct wl_priv *wl;
s32 err = 0;
@@ -6341,17 +6451,16 @@
if (err)
WL_ERR(("__wl_cfg80211_up failed\n"));
mutex_unlock(&wl->usr_sync);
-
return err;
}
-/* Private Event to Supplicant with indication that FW hangs */
+/* Private Event to Supplicant with indication that chip hangs */
int wl_cfg80211_hang(struct net_device *dev, u16 reason)
{
struct wl_priv *wl;
wl = wlcfg_drv_priv;
- WL_ERR(("In : FW crash Eventing\n"));
+ WL_ERR(("In : chip crash eventing\n"));
cfg80211_disconnected(dev, reason, NULL, 0, GFP_KERNEL);
if (wl != NULL) {
wl_link_down(wl);
@@ -6359,7 +6468,7 @@
return 0;
}
-s32 wl_cfg80211_down(void)
+s32 wl_cfg80211_down(void *para)
{
struct wl_priv *wl;
s32 err = 0;
@@ -6373,84 +6482,79 @@
return err;
}
-static s32 wl_dongle_probecap(struct wl_priv *wl)
-{
- s32 err = 0;
-
- err = wl_update_wiphybands(wl);
- if (unlikely(err))
- return err;
-
- return err;
-}
-
-static void *wl_read_prof(struct wl_priv *wl, s32 item)
+static void *wl_read_prof(struct wl_priv *wl, struct net_device *ndev, s32 item)
{
unsigned long flags;
void *rptr = NULL;
+ struct wl_profile *profile = wl_get_profile_by_netdev(wl, ndev);
- flags = dhd_os_spin_lock((dhd_pub_t *)(wl->pub));
+ if (!profile)
+ return NULL;
+ spin_lock_irqsave(&wl->cfgdrv_lock, flags);
switch (item) {
case WL_PROF_SEC:
- rptr = &wl->profile->sec;
+ rptr = &profile->sec;
break;
case WL_PROF_ACT:
- rptr = &wl->profile->active;
+ rptr = &profile->active;
break;
case WL_PROF_BSSID:
- rptr = &wl->profile->bssid;
+ rptr = profile->bssid;
break;
case WL_PROF_SSID:
- rptr = &wl->profile->ssid;
+ rptr = &profile->ssid;
break;
}
- dhd_os_spin_unlock((dhd_pub_t *)(wl->pub), flags);
+ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
if (!rptr)
WL_ERR(("invalid item (%d)\n", item));
return rptr;
}
static s32
-wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e, void *data,
- s32 item)
+wl_update_prof(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e, void *data, s32 item)
{
s32 err = 0;
struct wlc_ssid *ssid;
unsigned long flags;
+ struct wl_profile *profile = wl_get_profile_by_netdev(wl, ndev);
- flags = dhd_os_spin_lock((dhd_pub_t *)(wl->pub));
+ if (!profile)
+ return WL_INVALID;
+ spin_lock_irqsave(&wl->cfgdrv_lock, flags);
switch (item) {
case WL_PROF_SSID:
ssid = (wlc_ssid_t *) data;
- memset(wl->profile->ssid.SSID, 0,
- sizeof(wl->profile->ssid.SSID));
- memcpy(wl->profile->ssid.SSID, ssid->SSID, ssid->SSID_len);
- wl->profile->ssid.SSID_len = ssid->SSID_len;
+ memset(profile->ssid.SSID, 0,
+ sizeof(profile->ssid.SSID));
+ memcpy(profile->ssid.SSID, ssid->SSID, ssid->SSID_len);
+ profile->ssid.SSID_len = ssid->SSID_len;
break;
case WL_PROF_BSSID:
if (data)
- memcpy(wl->profile->bssid, data, ETHER_ADDR_LEN);
+ memcpy(profile->bssid, data, ETHER_ADDR_LEN);
else
- memset(wl->profile->bssid, 0, ETHER_ADDR_LEN);
+ memset(profile->bssid, 0, ETHER_ADDR_LEN);
break;
case WL_PROF_SEC:
- memcpy(&wl->profile->sec, data, sizeof(wl->profile->sec));
+ memcpy(&profile->sec, data, sizeof(profile->sec));
break;
case WL_PROF_ACT:
- wl->profile->active = *(bool *)data;
+ profile->active = *(bool *)data;
break;
case WL_PROF_BEACONINT:
- wl->profile->beacon_interval = *(u16 *)data;
+ profile->beacon_interval = *(u16 *)data;
break;
case WL_PROF_DTIMPERIOD:
- wl->profile->dtim_period = *(u8 *)data;
+ profile->dtim_period = *(u8 *)data;
break;
default:
WL_ERR(("unsupported item (%d)\n", item));
err = -EOPNOTSUPP;
break;
}
- dhd_os_spin_unlock((dhd_pub_t *)(wl->pub), flags);
+ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
return err;
}
@@ -6467,7 +6571,7 @@
static bool wl_is_ibssmode(struct wl_priv *wl, struct net_device *ndev)
{
- return get_mode_by_netdev(wl, ndev) == WL_MODE_IBSS;
+ return wl_get_mode_by_netdev(wl, ndev) == WL_MODE_IBSS;
}
static __used bool wl_is_ibssstarter(struct wl_priv *wl)
@@ -6578,114 +6682,28 @@
}
}
-s32 wl_cfg80211_read_fw(s8 *buf, u32 size)
-{
- const struct firmware *fw_entry;
- struct wl_priv *wl;
-
- wl = wlcfg_drv_priv;
-
- fw_entry = wl->fw->fw_entry;
-
- if (fw_entry->size < wl->fw->ptr + size)
- size = fw_entry->size - wl->fw->ptr;
-
- memcpy(buf, &fw_entry->data[wl->fw->ptr], size);
- wl->fw->ptr += size;
- return size;
-}
-
-void wl_cfg80211_release_fw(void)
-{
- struct wl_priv *wl;
-
- wl = wlcfg_drv_priv;
- release_firmware(wl->fw->fw_entry);
- wl->fw->ptr = 0;
-}
-
-void *wl_cfg80211_request_fw(s8 *file_name)
-{
- struct wl_priv *wl;
- const struct firmware *fw_entry = NULL;
- s32 err = 0;
-
- WL_TRACE(("In\n"));
- WL_DBG(("file name : \"%s\"\n", file_name));
- wl = wlcfg_drv_priv;
-
- if (!test_bit(WL_FW_LOADING_DONE, &wl->fw->status)) {
- err = request_firmware(&wl->fw->fw_entry, file_name,
- &wl_cfg80211_get_sdio_func()->dev);
- if (unlikely(err)) {
- WL_ERR(("Could not download fw (%d)\n", err));
- goto req_fw_out;
- }
- set_bit(WL_FW_LOADING_DONE, &wl->fw->status);
- fw_entry = wl->fw->fw_entry;
- if (fw_entry) {
- WL_DBG(("fw size (%zd), data (%p)\n", fw_entry->size,
- fw_entry->data));
- }
- } else if (!test_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status)) {
- err = request_firmware(&wl->fw->fw_entry, file_name,
- &wl_cfg80211_get_sdio_func()->dev);
- if (unlikely(err)) {
- WL_ERR(("Could not download nvram (%d)\n", err));
- goto req_fw_out;
- }
- set_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status);
- fw_entry = wl->fw->fw_entry;
- if (fw_entry) {
- WL_DBG(("nvram size (%zd), data (%p)\n", fw_entry->size,
- fw_entry->data));
- }
- } else {
- WL_DBG(("Downloading already done. Nothing to do more\n"));
- err = -EPERM;
- }
-
-req_fw_out:
- if (unlikely(err)) {
- return NULL;
- }
- wl->fw->ptr = 0;
- return (void *)fw_entry->data;
-}
-
-s8 *wl_cfg80211_get_fwname(void)
-{
- struct wl_priv *wl;
-
- wl = wlcfg_drv_priv;
- strcpy(wl->fw->fw_name, WL_4329_FW_FILE);
- return wl->fw->fw_name;
-}
-
-s8 *wl_cfg80211_get_nvramname(void)
-{
- struct wl_priv *wl;
-
- wl = wlcfg_drv_priv;
- strcpy(wl->fw->nvram_name, WL_4329_NVRAM_FILE);
- return wl->fw->nvram_name;
-}
-
s32 wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr)
{
- struct wl_priv *wl;
- dhd_pub_t *dhd_pub;
+ struct wl_priv *wl = wlcfg_drv_priv;
struct ether_addr p2pif_addr;
+ struct ether_addr primary_mac;
- wl = wlcfg_drv_priv;
- dhd_pub = (dhd_pub_t *)wl->pub;
- wl_cfgp2p_generate_bss_mac(&dhd_pub->mac, p2pdev_addr, &p2pif_addr);
+ if (!wl->p2p)
+ return -1;
+ if (!p2p_is_on(wl)) {
+ get_primary_mac(wl, &primary_mac);
+ wl_cfgp2p_generate_bss_mac(&primary_mac, p2pdev_addr, &p2pif_addr);
+ } else {
+ memcpy(p2pdev_addr->octet,
+ wl->p2p->dev_addr.octet, ETHER_ADDR_LEN);
+ }
return 0;
}
s32 wl_cfg80211_set_p2p_noa(struct net_device *net, char* buf, int len)
{
struct wl_priv *wl;
+
wl = wlcfg_drv_priv;
return wl_cfgp2p_set_p2p_noa(wl, net, buf, len);
@@ -6719,8 +6737,8 @@
if (wl->p2p && wl->p2p->vif_created) {
ndev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION);
bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION);
- } else if (wl_get_drv_status(wl, AP_CREATING) ||
- wl_get_drv_status(wl, AP_CREATED)) {
+ } else if (wl_get_drv_status(wl, AP_CREATING, net) ||
+ wl_get_drv_status(wl, AP_CREATED, net)) {
ndev = net;
bssidx = 0;
}
@@ -6743,69 +6761,6 @@
return ret;
}
-static __used void wl_dongle_poweron(struct wl_priv *wl)
-{
- WL_DBG(("Enter \n"));
- dhd_customer_gpio_wlan_ctrl(WLAN_RESET_ON);
-
-#if defined(BCMLXSDMMC)
- sdioh_start(NULL, 0);
-#endif
-#if defined(BCMLXSDMMC)
- sdioh_start(NULL, 1);
-#endif
- wl_cfg80211_resume(wl_to_wiphy(wl));
-}
-
-static __used void wl_dongle_poweroff(struct wl_priv *wl)
-{
- WL_DBG(("Enter \n"));
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
- wl_cfg80211_suspend(wl_to_wiphy(wl), NULL);
-#else
- wl_cfg80211_suspend(wl_to_wiphy(wl));
-#endif
-
-#if defined(BCMLXSDMMC)
- sdioh_stop(NULL);
-#endif
- /* clean up dtim_skip setting */
- dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF);
-}
-
-static int wl_debugfs_add_netdev_params(struct wl_priv *wl)
-{
- char buf[10+IFNAMSIZ];
- struct dentry *fd;
- s32 err = 0;
-
- WL_TRACE(("In\n"));
- sprintf(buf, "netdev:%s", wl_to_prmry_ndev(wl)->name);
- wl->debugfsdir = debugfs_create_dir(buf, wl_to_wiphy(wl)->debugfsdir);
-
- fd = debugfs_create_u16("beacon_int", S_IRUGO, wl->debugfsdir,
- (u16 *)&wl->profile->beacon_interval);
- if (!fd) {
- err = -ENOMEM;
- goto err_out;
- }
-
- fd = debugfs_create_u8("dtim_period", S_IRUGO, wl->debugfsdir,
- (u8 *)&wl->profile->dtim_period);
- if (!fd) {
- err = -ENOMEM;
- goto err_out;
- }
-
-err_out:
- return err;
-}
-
-static void wl_debugfs_remove_netdev(struct wl_priv *wl)
-{
- WL_DBG(("Enter \n"));
-}
-
static const struct rfkill_ops wl_rfkill_ops = {
.set_block = wl_rfkill_set
};
@@ -6834,7 +6789,7 @@
return -EINVAL;
if (setup) {
wl->rfkill = rfkill_alloc("brcmfmac-wifi",
- &wl_cfg80211_get_sdio_func()->dev,
+ wl_cfg80211_get_parent_dev(),
RFKILL_TYPE_WLAN, &wl_rfkill_ops, (void *)wl);
if (!wl->rfkill) {
@@ -6860,471 +6815,42 @@
return err;
}
-#if defined(COEX_DHCP)
-/*
- * get named driver variable to uint register value and return error indication
- * calling example: dev_wlc_intvar_get_reg(dev, "btc_params",66, ®_value)
- */
-static int
-dev_wlc_intvar_get_reg(struct net_device *dev, char *name,
- uint reg, int *retval)
+struct device *wl_cfg80211_get_parent_dev(void)
{
- union {
- char buf[WLC_IOCTL_SMLEN];
- int val;
- } var;
- int error;
-
- bcm_mkiovar(name, (char *)(®), sizeof(reg),
- (char *)(&var), sizeof(var.buf));
- error = wldev_ioctl(dev, WLC_GET_VAR, (char *)(&var), sizeof(var.buf), false);
-
- *retval = dtoh32(var.val);
- return (error);
+ return cfg80211_parent_dev;
}
-static int
-dev_wlc_bufvar_set(struct net_device *dev, char *name, char *buf, int len)
+void wl_cfg80211_set_parent_dev(void *dev)
{
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)
- char ioctlbuf[1024];
-#else
- static char ioctlbuf[1024];
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) */
-
- bcm_mkiovar(name, buf, len, ioctlbuf, sizeof(ioctlbuf));
-
- return (wldev_ioctl(dev, WLC_SET_VAR, ioctlbuf, sizeof(ioctlbuf), true));
-}
-/*
-get named driver variable to uint register value and return error indication
-calling example: dev_wlc_intvar_set_reg(dev, "btc_params",66, value)
-*/
-static int
-dev_wlc_intvar_set_reg(struct net_device *dev, char *name, char *addr, char * val)
-{
- char reg_addr[8];
-
- memset(reg_addr, 0, sizeof(reg_addr));
- memcpy((char *)®_addr[0], (char *)addr, 4);
- memcpy((char *)®_addr[4], (char *)val, 4);
-
- return (dev_wlc_bufvar_set(dev, name, (char *)®_addr[0], sizeof(reg_addr)));
+ cfg80211_parent_dev = dev;
}
-static bool btcoex_is_sco_active(struct net_device *dev)
+static void wl_cfg80211_clear_parent_dev(void)
{
- int ioc_res = 0;
- bool res = FALSE;
- int sco_id_cnt = 0;
- int param27;
- int i;
-
- for (i = 0; i < 12; i++) {
-
- ioc_res = dev_wlc_intvar_get_reg(dev, "btc_params", 27, ¶m27);
-
- WL_TRACE(("%s, sample[%d], btc params: 27:%x\n",
- __FUNCTION__, i, param27));
-
- if (ioc_res < 0) {
- WL_ERR(("%s ioc read btc params error\n", __FUNCTION__));
- break;
- }
-
- if ((param27 & 0x6) == 2) { /* count both sco & esco */
- sco_id_cnt++;
- }
-
- if (sco_id_cnt > 2) {
- WL_TRACE(("%s, sco/esco detected, pkt id_cnt:%d samples:%d\n",
- __FUNCTION__, sco_id_cnt, i));
- res = TRUE;
- break;
- }
-
- msleep(5);
- }
-
- return res;
+ cfg80211_parent_dev = NULL;
}
-#if defined(BT_DHCP_eSCO_FIX)
-/* Enhanced BT COEX settings for eSCO compatibility during DHCP window */
-static int set_btc_esco_params(struct net_device *dev, bool trump_sco)
+static void get_primary_mac(struct wl_priv *wl, struct ether_addr *mac)
{
- static bool saved_status = FALSE;
+ wldev_iovar_getbuf_bsscfg(wl_to_prmry_ndev(wl), "cur_etheraddr", NULL,
+ 0, wl->ioctl_buf, WLC_IOCTL_MAXLEN, 0, &wl->ioctl_buf_sync);
+ memcpy(mac->octet, wl->ioctl_buf, ETHER_ADDR_LEN);
+}
- char buf_reg50va_dhcp_on[8] =
- { 50, 00, 00, 00, 0x22, 0x80, 0x00, 0x00 };
- char buf_reg51va_dhcp_on[8] =
- { 51, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 };
- char buf_reg64va_dhcp_on[8] =
- { 64, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 };
- char buf_reg65va_dhcp_on[8] =
- { 65, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 };
- char buf_reg71va_dhcp_on[8] =
- { 71, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 };
- uint32 regaddr;
- static uint32 saved_reg50;
- static uint32 saved_reg51;
- static uint32 saved_reg64;
- static uint32 saved_reg65;
- static uint32 saved_reg71;
+int wl_cfg80211_do_driver_init(struct net_device *net)
+{
+ struct wl_priv *wl = *(struct wl_priv **)netdev_priv(net);
- if (trump_sco) {
- /* this should reduce eSCO agressive retransmit
- * w/o breaking it
- */
+ if (!wl || !wl->wdev)
+ return -EINVAL;
- /* 1st save current */
- WL_TRACE(("Do new SCO/eSCO coex algo {save &"
- "override}\n"));
- if ((!dev_wlc_intvar_get_reg(dev, "btc_params", 50, &saved_reg50)) &&
- (!dev_wlc_intvar_get_reg(dev, "btc_params", 51, &saved_reg51)) &&
- (!dev_wlc_intvar_get_reg(dev, "btc_params", 64, &saved_reg64)) &&
- (!dev_wlc_intvar_get_reg(dev, "btc_params", 65, &saved_reg65)) &&
- (!dev_wlc_intvar_get_reg(dev, "btc_params", 71, &saved_reg71))) {
- saved_status = TRUE;
- WL_TRACE(("%s saved bt_params[50,51,64,65,71]:"
- "0x%x 0x%x 0x%x 0x%x 0x%x\n",
- __FUNCTION__, saved_reg50, saved_reg51,
- saved_reg64, saved_reg65, saved_reg71));
- } else {
- WL_ERR((":%s: save btc_params failed\n",
- __FUNCTION__));
- saved_status = FALSE;
- return -1;
- }
-
- WL_TRACE(("override with [50,51,64,65,71]:"
- "0x%x 0x%x 0x%x 0x%x 0x%x\n",
- *(u32 *)(buf_reg50va_dhcp_on+4),
- *(u32 *)(buf_reg51va_dhcp_on+4),
- *(u32 *)(buf_reg64va_dhcp_on+4),
- *(u32 *)(buf_reg65va_dhcp_on+4),
- *(u32 *)(buf_reg71va_dhcp_on+4)));
-
- dev_wlc_bufvar_set(dev, "btc_params",
- (char *)&buf_reg50va_dhcp_on[0], 8);
- dev_wlc_bufvar_set(dev, "btc_params",
- (char *)&buf_reg51va_dhcp_on[0], 8);
- dev_wlc_bufvar_set(dev, "btc_params",
- (char *)&buf_reg64va_dhcp_on[0], 8);
- dev_wlc_bufvar_set(dev, "btc_params",
- (char *)&buf_reg65va_dhcp_on[0], 8);
- dev_wlc_bufvar_set(dev, "btc_params",
- (char *)&buf_reg71va_dhcp_on[0], 8);
-
- saved_status = TRUE;
- } else if (saved_status) {
- /* restore previously saved bt params */
- WL_TRACE(("Do new SCO/eSCO coex algo {save &"
- "override}\n"));
-
- regaddr = 50;
- dev_wlc_intvar_set_reg(dev, "btc_params",
- (char *)®addr, (char *)&saved_reg50);
- regaddr = 51;
- dev_wlc_intvar_set_reg(dev, "btc_params",
- (char *)®addr, (char *)&saved_reg51);
- regaddr = 64;
- dev_wlc_intvar_set_reg(dev, "btc_params",
- (char *)®addr, (char *)&saved_reg64);
- regaddr = 65;
- dev_wlc_intvar_set_reg(dev, "btc_params",
- (char *)®addr, (char *)&saved_reg65);
- regaddr = 71;
- dev_wlc_intvar_set_reg(dev, "btc_params",
- (char *)®addr, (char *)&saved_reg71);
-
- WL_TRACE(("restore bt_params[50,51,64,65,71]:"
- "0x%x 0x%x 0x%x 0x%x 0x%x\n",
- saved_reg50, saved_reg51, saved_reg64,
- saved_reg65, saved_reg71));
-
- saved_status = FALSE;
- } else {
- WL_ERR((":%s att to restore not saved BTCOEX params\n",
- __FUNCTION__));
+ if (dhd_do_driver_init(wl->wdev->netdev) < 0)
return -1;
- }
- return 0;
-}
-#endif /* BT_DHCP_eSCO_FIX */
-static void
-wl_cfg80211_bt_setflag(struct net_device *dev, bool set)
-{
-#if defined(BT_DHCP_USE_FLAGS)
- char buf_flag7_dhcp_on[8] = { 7, 00, 00, 00, 0x1, 0x0, 0x00, 0x00 };
- char buf_flag7_default[8] = { 7, 00, 00, 00, 0x0, 0x00, 0x00, 0x00};
-#endif
-
-#if defined(BT_DHCP_eSCO_FIX)
- /* set = 1, save & turn on 0 - off & restore prev settings */
- set_btc_esco_params(dev, set);
-#endif
-
-#if defined(BT_DHCP_USE_FLAGS)
- WL_TRACE(("WI-FI priority boost via bt flags, set:%d\n", set));
- if (set == TRUE)
- /* Forcing bt_flag7 */
- dev_wlc_bufvar_set(dev, "btc_flags",
- (char *)&buf_flag7_dhcp_on[0],
- sizeof(buf_flag7_dhcp_on));
- else
- /* Restoring default bt flag7 */
- dev_wlc_bufvar_set(dev, "btc_flags",
- (char *)&buf_flag7_default[0],
- sizeof(buf_flag7_default));
-#endif
-}
-
-static void wl_cfg80211_bt_timerfunc(ulong data)
-{
- struct btcoex_info *bt_local = (struct btcoex_info *)data;
- WL_TRACE(("%s\n", __FUNCTION__));
- bt_local->timer_on = 0;
- schedule_work(&bt_local->work);
-}
-
-static void wl_cfg80211_bt_handler(struct work_struct *work)
-{
- struct btcoex_info *btcx_inf;
-
- btcx_inf = container_of(work, struct btcoex_info, work);
-
- if (btcx_inf->timer_on) {
- btcx_inf->timer_on = 0;
- del_timer_sync(&btcx_inf->timer);
- }
-
- switch (btcx_inf->bt_state) {
- case BT_DHCP_START:
- /* DHCP started
- * provide OPPORTUNITY window to get DHCP address
- */
- WL_TRACE(("%s bt_dhcp stm: started \n",
- __FUNCTION__));
- btcx_inf->bt_state = BT_DHCP_OPPR_WIN;
- mod_timer(&btcx_inf->timer,
- jiffies + BT_DHCP_OPPR_WIN_TIME*HZ/1000);
- btcx_inf->timer_on = 1;
- break;
-
- case BT_DHCP_OPPR_WIN:
- if (btcx_inf->dhcp_done) {
- WL_TRACE(("%s DHCP Done before T1 expiration\n",
- __FUNCTION__));
- goto btc_coex_idle;
- }
-
- /* DHCP is not over yet, start lowering BT priority
- * enforce btc_params + flags if necessary
- */
- WL_TRACE(("%s DHCP T1:%d expired\n", __FUNCTION__,
- BT_DHCP_OPPR_WIN_TIME));
- if (btcx_inf->dev)
- wl_cfg80211_bt_setflag(btcx_inf->dev, TRUE);
- btcx_inf->bt_state = BT_DHCP_FLAG_FORCE_TIMEOUT;
- mod_timer(&btcx_inf->timer,
- jiffies + BT_DHCP_FLAG_FORCE_TIME*HZ/1000);
- btcx_inf->timer_on = 1;
- break;
-
- case BT_DHCP_FLAG_FORCE_TIMEOUT:
- if (btcx_inf->dhcp_done) {
- WL_TRACE(("%s DHCP Done before T2 expiration\n",
- __FUNCTION__));
- } else {
- /* Noo dhcp during T1+T2, restore BT priority */
- WL_TRACE(("%s DHCP wait interval T2:%d"
- "msec expired\n", __FUNCTION__,
- BT_DHCP_FLAG_FORCE_TIME));
- }
-
- /* Restoring default bt priority */
- if (btcx_inf->dev)
- wl_cfg80211_bt_setflag(btcx_inf->dev, FALSE);
-btc_coex_idle:
- btcx_inf->bt_state = BT_DHCP_IDLE;
- btcx_inf->timer_on = 0;
- break;
-
- default:
- WL_ERR(("%s error g_status=%d !!!\n", __FUNCTION__,
- btcx_inf->bt_state));
- if (btcx_inf->dev)
- wl_cfg80211_bt_setflag(btcx_inf->dev, FALSE);
- btcx_inf->bt_state = BT_DHCP_IDLE;
- btcx_inf->timer_on = 0;
- break;
- }
-
- net_os_wake_unlock(btcx_inf->dev);
-}
-
-static int wl_cfg80211_btcoex_init(struct wl_priv *wl)
-{
- struct btcoex_info *btco_inf = NULL;
-
- btco_inf = kmalloc(sizeof(struct btcoex_info), GFP_KERNEL);
- if (!btco_inf)
- return -ENOMEM;
-
- btco_inf->bt_state = BT_DHCP_IDLE;
- btco_inf->ts_dhcp_start = 0;
- btco_inf->ts_dhcp_ok = 0;
- /* Set up timer for BT */
- btco_inf->timer_ms = 10;
- init_timer(&btco_inf->timer);
- btco_inf->timer.data = (ulong)btco_inf;
- btco_inf->timer.function = wl_cfg80211_bt_timerfunc;
-
- btco_inf->dev = wl->wdev->netdev;
-
- INIT_WORK(&btco_inf->work, wl_cfg80211_bt_handler);
-
- wl->btcoex_info = btco_inf;
return 0;
}
-static void
-wl_cfg80211_btcoex_deinit(struct wl_priv *wl)
+void wl_cfg80211_enable_trace(int level)
{
- if (!wl->btcoex_info)
- return;
-
- if (!wl->btcoex_info->timer_on) {
- wl->btcoex_info->timer_on = 0;
- del_timer_sync(&wl->btcoex_info->timer);
- }
-
- cancel_work_sync(&wl->btcoex_info->work);
-
- kfree(wl->btcoex_info);
- wl->btcoex_info = NULL;
-}
-#endif /* COEX_DHCP */
-
-int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, char *command)
-{
- char powermode_val = 0;
- char buf_reg66va_dhcp_on[8] = { 66, 00, 00, 00, 0x10, 0x27, 0x00, 0x00 };
- char buf_reg41va_dhcp_on[8] = { 41, 00, 00, 00, 0x33, 0x00, 0x00, 0x00 };
- char buf_reg68va_dhcp_on[8] = { 68, 00, 00, 00, 0x90, 0x01, 0x00, 0x00 };
-
- uint32 regaddr;
- static uint32 saved_reg66;
- static uint32 saved_reg41;
- static uint32 saved_reg68;
- static bool saved_status = FALSE;
-
-#ifdef COEX_DHCP
- char buf_flag7_default[8] = { 7, 00, 00, 00, 0x0, 0x00, 0x00, 0x00};
- struct btcoex_info *btco_inf = wlcfg_drv_priv->btcoex_info;
-#endif /* COEX_DHCP */
-
- /* Figure out powermode 1 or o command */
- strncpy((char *)&powermode_val, command + strlen("BTCOEXMODE") +1, 1);
-
- if (strnicmp((char *)&powermode_val, "1", strlen("1")) == 0) {
-
- WL_TRACE(("%s: DHCP session starts\n", __FUNCTION__));
-
- /* Retrieve and saved orig regs value */
- if ((saved_status == FALSE) &&
- (!dev_wlc_intvar_get_reg(dev, "btc_params", 66, &saved_reg66)) &&
- (!dev_wlc_intvar_get_reg(dev, "btc_params", 41, &saved_reg41)) &&
- (!dev_wlc_intvar_get_reg(dev, "btc_params", 68, &saved_reg68))) {
- saved_status = TRUE;
- WL_TRACE(("Saved 0x%x 0x%x 0x%x\n",
- saved_reg66, saved_reg41, saved_reg68));
-
- /* Disable PM mode during dhpc session */
-
- /* Disable PM mode during dhpc session */
-#ifdef COEX_DHCP
- /* Start BT timer only for SCO connection */
- if (btcoex_is_sco_active(dev)) {
- /* btc_params 66 */
- dev_wlc_bufvar_set(dev, "btc_params",
- (char *)&buf_reg66va_dhcp_on[0],
- sizeof(buf_reg66va_dhcp_on));
- /* btc_params 41 0x33 */
- dev_wlc_bufvar_set(dev, "btc_params",
- (char *)&buf_reg41va_dhcp_on[0],
- sizeof(buf_reg41va_dhcp_on));
- /* btc_params 68 0x190 */
- dev_wlc_bufvar_set(dev, "btc_params",
- (char *)&buf_reg68va_dhcp_on[0],
- sizeof(buf_reg68va_dhcp_on));
- saved_status = TRUE;
-
- btco_inf->bt_state = BT_DHCP_START;
- btco_inf->timer_on = 1;
- mod_timer(&btco_inf->timer, btco_inf->timer.expires);
- WL_TRACE(("%s enable BT DHCP Timer\n",
- __FUNCTION__));
- }
-#endif /* COEX_DHCP */
- }
- else if (saved_status == TRUE) {
- WL_ERR(("%s was called w/o DHCP OFF. Continue\n", __FUNCTION__));
- }
- }
- else if (strnicmp((char *)&powermode_val, "2", strlen("2")) == 0) {
-
-
- /* Restoring PM mode */
-
-#ifdef COEX_DHCP
- /* Stop any bt timer because DHCP session is done */
- WL_TRACE(("%s disable BT DHCP Timer\n", __FUNCTION__));
- if (btco_inf->timer_on) {
- btco_inf->timer_on = 0;
- del_timer_sync(&btco_inf->timer);
-
- if (btco_inf->bt_state != BT_DHCP_IDLE) {
- /* need to restore original btc flags & extra btc params */
- WL_TRACE(("%s bt->bt_state:%d\n",
- __FUNCTION__, btco_inf->bt_state));
- /* wake up btcoex thread to restore btlags+params */
- schedule_work(&btco_inf->work);
- }
- }
-
- /* Restoring btc_flag paramter anyway */
- if (saved_status == TRUE)
- dev_wlc_bufvar_set(dev, "btc_flags",
- (char *)&buf_flag7_default[0], sizeof(buf_flag7_default));
-#endif /* COEX_DHCP */
-
- /* Restore original values */
- if (saved_status == TRUE) {
- regaddr = 66;
- dev_wlc_intvar_set_reg(dev, "btc_params",
- (char *)®addr, (char *)&saved_reg66);
- regaddr = 41;
- dev_wlc_intvar_set_reg(dev, "btc_params",
- (char *)®addr, (char *)&saved_reg41);
- regaddr = 68;
- dev_wlc_intvar_set_reg(dev, "btc_params",
- (char *)®addr, (char *)&saved_reg68);
-
- WL_TRACE(("restore regs {66,41,68} <- 0x%x 0x%x 0x%x\n",
- saved_reg66, saved_reg41, saved_reg68));
- }
- saved_status = FALSE;
-
- }
- else {
- WL_ERR(("%s Unkwown yet power setting, ignored\n",
- __FUNCTION__));
- }
-
- snprintf(command, 3, "OK");
-
- return (strlen("OK"));
+ wl_dbg_level |= WL_DBG_DBG;
}
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.h b/drivers/net/wireless/bcmdhd/wl_cfg80211.h
index 262335e..2b8e664 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.h
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.h
@@ -68,6 +68,9 @@
printk args; \
} \
} while (0)
+#ifdef WL_INFO
+#undef WL_INFO
+#endif
#define WL_INFO(args) \
do { \
if (wl_dbg_level & WL_DBG_INFO) { \
@@ -75,6 +78,9 @@
printk args; \
} \
} while (0)
+#ifdef WL_SCAN
+#undef WL_SCAN
+#endif
#define WL_SCAN(args) \
do { \
if (wl_dbg_level & WL_DBG_SCAN) { \
@@ -82,6 +88,9 @@
printk args; \
} \
} while (0)
+#ifdef WL_TRACE
+#undef WL_TRACE
+#endif
#define WL_TRACE(args) \
do { \
if (wl_dbg_level & WL_DBG_TRACE) { \
@@ -102,39 +111,30 @@
#endif /* (WL_DBG_LEVEL > 0) */
-#define WL_SCAN_RETRY_MAX 3 /* used for ibss scan */
-#define WL_NUM_PMKIDS_MAX MAXPMKID /* will be used
- * for 2.6.33 kernel
- * or later
- */
-#define WL_SCAN_BUF_MAX (1024 * 8)
-#define WL_TLV_INFO_MAX 1024
+#define WL_SCAN_RETRY_MAX 3
+#define WL_NUM_PMKIDS_MAX MAXPMKID
+#define WL_SCAN_BUF_MAX (1024 * 8)
+#define WL_TLV_INFO_MAX 1024
#define WL_SCAN_IE_LEN_MAX 2048
-#define WL_BSS_INFO_MAX 2048
-#define WL_ASSOC_INFO_MAX 512 /*
- * needs to grab assoc info from dongle to
- * report it to cfg80211 through "connect"
- * event
- */
+#define WL_BSS_INFO_MAX 2048
+#define WL_ASSOC_INFO_MAX 512
#define WL_IOCTL_LEN_MAX 1024
#define WL_EXTRA_BUF_MAX 2048
-#define WL_ISCAN_BUF_MAX 2048 /*
- * the buf lengh can be WLC_IOCTL_MAXLEN (8K)
- * to reduce iteration
- */
+#define WL_ISCAN_BUF_MAX 2048
#define WL_ISCAN_TIMER_INTERVAL_MS 3000
#define WL_SCAN_ERSULTS_LAST (WL_SCAN_RESULTS_NO_MEM+1)
-#define WL_AP_MAX 256 /* virtually unlimitted as long
- * as kernel memory allows
- */
+#define WL_AP_MAX 256
#define WL_FILE_NAME_MAX 256
-#define WL_DWELL_TIME 200
-#define WL_LONG_DWELL_TIME 1000
-#define VWDEV_CNT 3
+#define WL_DWELL_TIME 200
+#define WL_MED_DWELL_TIME 400
+#define WL_LONG_DWELL_TIME 1000
+#define IFACE_MAX_CNT 2
#define WL_SCAN_TIMER_INTERVAL_MS 8000 /* Scan timeout */
+#define WL_CHANNEL_SYNC_RETRY 5
+#define WL_INVALID -1
-/* dongle status */
+/* driver status */
enum wl_status {
WL_STATUS_READY = 0,
WL_STATUS_SCANNING,
@@ -143,7 +143,8 @@
WL_STATUS_CONNECTED,
WL_STATUS_DISCONNECTING,
WL_STATUS_AP_CREATING,
- WL_STATUS_AP_CREATED
+ WL_STATUS_AP_CREATED,
+ WL_STATUS_SENDING_ACT_FRM
};
/* wi-fi mode */
@@ -153,7 +154,7 @@
WL_MODE_AP
};
-/* dongle profile list */
+/* driver profile list */
enum wl_prof_list {
WL_PROF_MODE,
WL_PROF_SSID,
@@ -166,7 +167,7 @@
WL_PROF_DTIMPERIOD
};
-/* dongle iscan state */
+/* driver iscan state */
enum wl_iscan_state {
WL_ISCAN_STATE_IDLE,
WL_ISCAN_STATE_SCANING
@@ -196,12 +197,8 @@
u8 variable[0];
} __attribute__ ((packed));
-/* dongle configuration */
+/* driver configuration */
struct wl_conf {
- struct net_mode {
- struct net_device *ndev;
- s32 type;
- } mode [VWDEV_CNT + 1]; /* adhoc , infrastructure or ap */
u32 frag_threshold;
u32 rts_threshold;
u32 retry_short;
@@ -259,22 +256,30 @@
u8 channel;
};
-/* dongle profile */
+/* wl driver profile */
struct wl_profile {
u32 mode;
+ s32 band;
struct wlc_ssid ssid;
+ struct wl_security sec;
+ struct wl_ibss ibss;
u8 bssid[ETHER_ADDR_LEN];
u16 beacon_interval;
u8 dtim_period;
- struct wl_security sec;
- struct wl_ibss ibss;
- s32 band;
bool active;
};
+struct net_info {
+ struct net_device *ndev;
+ struct wireless_dev *wdev;
+ struct wl_profile profile;
+ s32 mode;
+ unsigned long sme_state;
+ struct list_head list; /* list of all net_info structure */
+};
typedef s32(*ISCAN_HANDLER) (struct wl_priv *wl);
-/* dongle iscan controller */
+/* iscan controller */
struct wl_iscan_ctrl {
struct net_device *dev;
struct timer_list timer;
@@ -323,9 +328,10 @@
#define ESCAN_BUF_SIZE (64 * 1024)
struct escan_info {
- u32 escan_state;
- u8 escan_buf[ESCAN_BUF_SIZE];
- struct wiphy *wiphy;
+ u32 escan_state;
+ u8 escan_buf[ESCAN_BUF_SIZE];
+ struct wiphy *wiphy;
+ struct net_device *ndev;
};
struct ap_info {
@@ -341,14 +347,14 @@
};
struct btcoex_info {
struct timer_list timer;
- uint32 timer_ms;
- uint32 timer_on;
- uint32 ts_dhcp_start; /* ms ts ecord time stats */
- uint32 ts_dhcp_ok; /* ms ts ecord time stats */
- bool dhcp_done; /* flag, indicates that host done with
- * dhcp before t1/t2 expiration
- */
- int bt_state;
+ u32 timer_ms;
+ u32 timer_on;
+ u32 ts_dhcp_start; /* ms ts ecord time stats */
+ u32 ts_dhcp_ok; /* ms ts ecord time stats */
+ bool dhcp_done; /* flag, indicates that host done with
+ * dhcp before t1/t2 expiration
+ */
+ s32 bt_state;
struct work_struct work;
struct net_device *dev;
};
@@ -360,40 +366,50 @@
u32 probe_req_ie_len;
u32 assoc_req_ie_len;
};
-/* dongle private data of cfg80211 interface */
+
+struct afx_hdl {
+ wl_af_params_t *pending_tx_act_frm;
+ struct ether_addr pending_tx_dst_addr;
+ struct net_device *dev;
+ struct work_struct work;
+ u32 bssidx;
+ u32 retry;
+ s32 peer_chan;
+ bool ack_recv;
+};
+
+/* private data of cfg80211 interface */
struct wl_priv {
struct wireless_dev *wdev; /* representing wl cfg80211 device */
- struct wireless_dev *vwdev[VWDEV_CNT];
- struct wl_conf *conf; /* dongle configuration */
+
+ struct wireless_dev *p2p_wdev; /* representing wl cfg80211 device for P2P */
+ struct net_device *p2p_net; /* reference to p2p0 interface */
+
+ struct wl_conf *conf;
struct cfg80211_scan_request *scan_request; /* scan request object */
EVENT_HANDLER evt_handler[WLC_E_LAST];
struct list_head eq_list; /* used for event queue */
+ struct list_head net_list; /* used for struct net_info */
spinlock_t eq_lock; /* for event queue synchronization */
- struct mutex usr_sync; /* maily for dongle up/down synchronization */
+ spinlock_t cfgdrv_lock; /* to protect scan status (and others if needed) */
+ struct completion act_frm_scan;
+ struct mutex usr_sync; /* maily for up/down synchronization */
struct wl_scan_results *bss_list;
struct wl_scan_results *scan_results;
/* scan request object for internal purpose */
struct wl_scan_req *scan_req_int;
-
- /* bss information for cfg80211 layer */
- struct wl_cfg80211_bss_info *bss_info;
/* information element object for internal purpose */
struct wl_ie ie;
-
- /* for synchronization of main event thread */
- struct wl_profile *profile; /* holding dongle profile */
struct wl_iscan_ctrl *iscan; /* iscan controller */
/* association information container */
struct wl_connect_info conn_info;
- /* control firwmare and nvram paramter downloading */
- struct wl_fw_ctrl *fw;
struct wl_pmk_list *pmk_list; /* wpa2 pmk list */
tsk_ctl_t event_tsk; /* task of main event handler thread */
- unsigned long status; /* current dongle status */
void *pub;
+ u32 iface_cnt;
u32 channel; /* current channel */
bool iscan_on; /* iscan on/off switch */
bool iscan_kickstart; /* indicate iscan already started */
@@ -403,12 +419,12 @@
bool ibss_starter; /* indicates this sta is ibss starter */
bool link_up; /* link/connection up flag */
- /* indicate whether dongle to support power save mode */
+ /* indicate whether chip to support power save mode */
bool pwr_save;
- bool dongle_up; /* indicate whether dongle up or not */
- bool roam_on; /* on/off switch for dongle self-roaming */
+ bool roam_on; /* on/off switch for self-roaming */
bool scan_tried; /* indicates if first scan attempted */
- u8 *ioctl_buf; /* ioctl buffer */
+ u8 *ioctl_buf; /* ioctl buffer */
+ struct mutex ioctl_buf_sync;
u8 *escan_ioctl_buf;
u8 *extra_buf; /* maily to grab assoc information */
struct dentry *debugfsdir;
@@ -416,8 +432,10 @@
bool rf_blocked;
struct ieee80211_channel remain_on_chan;
enum nl80211_channel_type remain_on_chan_type;
- u64 cache_cookie;
- wait_queue_head_t dongle_event_wait;
+ u64 send_action_id;
+ u64 last_roc_id;
+ wait_queue_head_t netif_change_event;
+ struct afx_hdl *afx_hdl;
struct ap_info *ap_info;
struct sta_info *sta_info;
struct p2p_info *p2p;
@@ -426,6 +444,152 @@
struct timer_list scan_timeout; /* Timer for catch scan event timeout */
};
+static inline struct wl_bss_info *next_bss(struct wl_scan_results *list, struct wl_bss_info *bss)
+{
+ return bss = bss ?
+ (struct wl_bss_info *)((uintptr) bss + dtoh32(bss->length)) : list->bss_info;
+}
+
+static inline s32
+wl_alloc_netinfo(struct wl_priv *wl, struct net_device *ndev,
+ struct wireless_dev * wdev, s32 mode)
+{
+ struct net_info *_net_info;
+ s32 err = 0;
+ if (wl->iface_cnt == IFACE_MAX_CNT)
+ return -ENOMEM;
+ _net_info = kzalloc(sizeof(struct net_info), GFP_KERNEL);
+ if (!_net_info)
+ err = -ENOMEM;
+ else {
+ _net_info->mode = mode;
+ _net_info->ndev = ndev;
+ _net_info->wdev = wdev;
+ wl->iface_cnt++;
+ list_add(&_net_info->list, &wl->net_list);
+ }
+ return err;
+}
+
+static inline void
+wl_dealloc_netinfo(struct wl_priv *wl, struct net_device *ndev)
+{
+ struct net_info *_net_info, *next;
+
+ list_for_each_entry_safe(_net_info, next, &wl->net_list, list) {
+ if (ndev && (_net_info->ndev == ndev)) {
+ list_del(&_net_info->list);
+ wl->iface_cnt--;
+ if (_net_info->wdev) {
+ kfree(_net_info->wdev);
+ ndev->ieee80211_ptr = NULL;
+ }
+ kfree(_net_info);
+ }
+ }
+}
+
+static inline void
+wl_delete_all_netinfo(struct wl_priv *wl)
+{
+ struct net_info *_net_info, *next;
+
+ list_for_each_entry_safe(_net_info, next, &wl->net_list, list) {
+ list_del(&_net_info->list);
+ if (_net_info->wdev)
+ kfree(_net_info->wdev);
+ kfree(_net_info);
+ }
+ wl->iface_cnt = 0;
+}
+
+static inline bool
+wl_get_status_all(struct wl_priv *wl, s32 status)
+
+{
+ struct net_info *_net_info, *next;
+ u32 cnt = 0;
+ list_for_each_entry_safe(_net_info, next, &wl->net_list, list) {
+ if (_net_info->ndev &&
+ test_bit(status, &_net_info->sme_state))
+ cnt++;
+ }
+ return cnt? true: false;
+}
+
+static inline void
+wl_set_status_by_netdev(struct wl_priv *wl, s32 status,
+ struct net_device *ndev, u32 op)
+{
+
+ struct net_info *_net_info, *next;
+
+ list_for_each_entry_safe(_net_info, next, &wl->net_list, list) {
+ if (ndev && (_net_info->ndev == ndev)) {
+ switch (op) {
+ case 1:
+ set_bit(status, &_net_info->sme_state);
+ break;
+ case 2:
+ clear_bit(status, &_net_info->sme_state);
+ break;
+ case 4:
+ change_bit(status, &_net_info->sme_state);
+ break;
+ }
+ }
+
+ }
+}
+
+static inline u32
+wl_get_status_by_netdev(struct wl_priv *wl, s32 status,
+ struct net_device *ndev)
+{
+ struct net_info *_net_info, *next;
+
+ list_for_each_entry_safe(_net_info, next, &wl->net_list, list) {
+ if (ndev && (_net_info->ndev == ndev))
+ return test_bit(status, &_net_info->sme_state);
+ }
+ return 0;
+}
+
+static inline s32
+wl_get_mode_by_netdev(struct wl_priv *wl, struct net_device *ndev)
+{
+ struct net_info *_net_info, *next;
+
+ list_for_each_entry_safe(_net_info, next, &wl->net_list, list) {
+ if (ndev && (_net_info->ndev == ndev))
+ return _net_info->mode;
+ }
+ return -1;
+}
+
+static inline void
+wl_set_mode_by_netdev(struct wl_priv *wl, struct net_device *ndev,
+ s32 mode)
+{
+ struct net_info *_net_info, *next;
+
+ list_for_each_entry_safe(_net_info, next, &wl->net_list, list) {
+ if (ndev && (_net_info->ndev == ndev))
+ _net_info->mode = mode;
+ }
+}
+
+static inline struct wl_profile *
+wl_get_profile_by_netdev(struct wl_priv *wl, struct net_device *ndev)
+{
+ struct net_info *_net_info, *next;
+
+ list_for_each_entry_safe(_net_info, next, &wl->net_list, list) {
+ if (ndev && (_net_info->ndev == ndev))
+ return &_net_info->profile;
+ }
+ return NULL;
+}
#define wl_to_wiphy(w) (w->wdev->wiphy)
#define wl_to_prmry_ndev(w) (w->wdev->netdev)
#define ndev_to_wl(n) (wdev_to_wl(n->ieee80211_ptr))
@@ -435,112 +599,51 @@
#define wl_to_iscan(w) (w->iscan)
#define wl_to_conn(w) (&w->conn_info)
#define wiphy_from_scan(w) (w->escan_info.wiphy)
-#define wl_get_drv_status(wl, stat) (test_bit(WL_STATUS_ ## stat, &(wl)->status))
-#define wl_set_drv_status(wl, stat) (set_bit(WL_STATUS_ ## stat, &(wl)->status))
-#define wl_clr_drv_status(wl, stat) (clear_bit(WL_STATUS_ ## stat, &(wl)->status))
-#define wl_chg_drv_status(wl, stat) (change_bit(WL_STATUS_ ## stat, &(wl)->status))
-
-static inline struct wl_bss_info *next_bss(struct wl_scan_results *list, struct wl_bss_info *bss)
-{
- return bss = bss ?
- (struct wl_bss_info *)((uintptr) bss + dtoh32(bss->length)) : list->bss_info;
-}
-static inline s32 alloc_idx_vwdev(struct wl_priv *wl)
-{
- s32 i = 0;
- for (i = 0; i < VWDEV_CNT; i++) {
- if (wl->vwdev[i] == NULL)
- return i;
- }
- return -1;
-}
-
-static inline s32 get_idx_vwdev_by_netdev(struct wl_priv *wl, struct net_device *ndev)
-{
- s32 i = 0;
- for (i = 0; i < VWDEV_CNT; i++) {
- if ((wl->vwdev[i] != NULL) && (wl->vwdev[i]->netdev == ndev))
- return i;
- }
- return -1;
-}
-
-static inline s32 get_mode_by_netdev(struct wl_priv *wl, struct net_device *ndev)
-{
- s32 i = 0;
- for (i = 0; i <= VWDEV_CNT; i++) {
- if (wl->conf->mode[i].ndev != NULL && (wl->conf->mode[i].ndev == ndev))
- return wl->conf->mode[i].type;
- }
- return -1;
-}
-static inline void set_mode_by_netdev(struct wl_priv *wl, struct net_device *ndev, s32 type)
-{
- s32 i = 0;
- for (i = 0; i <= VWDEV_CNT; i++) {
- if (type == -1) {
- /* free the info of netdev */
- if (wl->conf->mode[i].ndev == ndev) {
- wl->conf->mode[i].ndev = NULL;
- wl->conf->mode[i].type = -1;
- break;
- }
-
- } else {
- if ((wl->conf->mode[i].ndev != NULL)&&
- (wl->conf->mode[i].ndev == ndev)) {
- /* update type of ndev */
- wl->conf->mode[i].type = type;
- break;
- }
- else if ((wl->conf->mode[i].ndev == NULL)&&
- (wl->conf->mode[i].type == -1)) {
- wl->conf->mode[i].ndev = ndev;
- wl->conf->mode[i].type = type;
- break;
- }
- }
- }
-}
-#define free_vwdev_by_index(wl, __i) do { \
- if (wl->vwdev[__i] != NULL) \
- kfree(wl->vwdev[__i]); \
- wl->vwdev[__i] = NULL; \
- } while (0)
+#define wl_get_drv_status_all(wl, stat) \
+ (wl_get_status_all(wl, WL_STATUS_ ## stat))
+#define wl_get_drv_status(wl, stat, ndev) \
+ (wl_get_status_by_netdev(wl, WL_STATUS_ ## stat, ndev))
+#define wl_set_drv_status(wl, stat, ndev) \
+ (wl_set_status_by_netdev(wl, WL_STATUS_ ## stat, ndev, 1))
+#define wl_clr_drv_status(wl, stat, ndev) \
+ (wl_set_status_by_netdev(wl, WL_STATUS_ ## stat, ndev, 2))
+#define wl_chg_drv_status(wl, stat, ndev) \
+ (wl_set_status_by_netdev(wl, WL_STATUS_ ## stat, ndev, 4))
#define for_each_bss(list, bss, __i) \
for (__i = 0; __i < list->count && __i < WL_AP_MAX; __i++, bss = next_bss(list, bss))
+#define for_each_ndev(wl, iter, next) \
+ list_for_each_entry_safe(iter, next, &wl->net_list, list)
+
+
/* In case of WPS from wpa_supplicant, pairwise siute and group suite is 0.
* In addtion to that, wpa_version is WPA_VERSION_1
*/
#define is_wps_conn(_sme) \
- ((_sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) && \
+ ((wl_cfgp2p_find_wpsie((u8 *)_sme->ie, _sme->ie_len) != NULL) && \
(!_sme->crypto.n_ciphers_pairwise) && \
(!_sme->crypto.cipher_group))
extern s32 wl_cfg80211_attach(struct net_device *ndev, void *data);
extern s32 wl_cfg80211_attach_post(struct net_device *ndev);
-extern void wl_cfg80211_detach(void);
-/* event handler from dongle */
+extern void wl_cfg80211_detach(void *para);
+
extern void wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t *e,
void *data);
-extern void wl_cfg80211_set_sdio_func(void *func); /* set sdio function info */
-extern struct sdio_func *wl_cfg80211_get_sdio_func(void); /* set sdio function info */
-extern s32 wl_cfg80211_up(void); /* dongle up */
-extern s32 wl_cfg80211_down(void); /* dongle down */
-extern s32 wl_cfg80211_notify_ifadd(struct net_device *net, s32 idx, s32 bssidx,
-int (*_net_attach)(dhd_pub_t *dhdp, int ifidx));
+void wl_cfg80211_set_parent_dev(void *dev);
+struct device *wl_cfg80211_get_parent_dev(void);
+
+extern s32 wl_cfg80211_up(void *para);
+extern s32 wl_cfg80211_down(void *para);
+extern s32 wl_cfg80211_notify_ifadd(struct net_device *ndev, s32 idx, s32 bssidx,
+ void* _net_attach);
+extern s32 wl_cfg80211_ifdel_ops(struct net_device *net);
extern s32 wl_cfg80211_notify_ifdel(struct net_device *ndev);
extern s32 wl_cfg80211_is_progress_ifadd(void);
extern s32 wl_cfg80211_is_progress_ifchange(void);
extern s32 wl_cfg80211_is_progress_ifadd(void);
extern s32 wl_cfg80211_notify_ifchange(void);
extern void wl_cfg80211_dbg_level(u32 level);
-extern void *wl_cfg80211_request_fw(s8 *file_name);
-extern s32 wl_cfg80211_read_fw(s8 *buf, u32 size);
-extern void wl_cfg80211_release_fw(void);
-extern s8 *wl_cfg80211_get_fwname(void);
-extern s8 *wl_cfg80211_get_nvramname(void);
extern s32 wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr);
extern s32 wl_cfg80211_set_p2p_noa(struct net_device *net, char* buf, int len);
extern s32 wl_cfg80211_get_p2p_noa(struct net_device *net, char* buf, int len);
@@ -548,11 +651,12 @@
enum wl_management_type type);
extern s32 wl_cfg80211_set_p2p_ps(struct net_device *net, char* buf, int len);
extern int wl_cfg80211_hang(struct net_device *dev, u16 reason);
+extern s32 wl_mode_to_nl80211_iftype(s32 mode);
+int wl_cfg80211_do_driver_init(struct net_device *net);
+void wl_cfg80211_enable_trace(int level);
/* do scan abort */
-extern s32
-wl_cfg80211_scan_abort(struct wl_priv *wl, struct net_device *ndev);
+extern s32 wl_cfg80211_scan_abort(struct wl_priv *wl, struct net_device *ndev);
-extern s32
-wl_cfg80211_if_is_group_owner(void);
+extern s32 wl_cfg80211_if_is_group_owner(void);
#endif /* _wl_cfg80211_h_ */
diff --git a/drivers/net/wireless/bcmdhd/wl_cfgp2p.c b/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
index 4ee6557..880123e 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
@@ -30,6 +30,7 @@
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/timer.h>
@@ -39,26 +40,197 @@
#include <bcmutils.h>
#include <bcmendian.h>
#include <proto/ethernet.h>
-#include <dngl_stats.h>
-#include <dhd.h>
-#include <dhdioctl.h>
-#include <wlioctl.h>
#include <wl_cfg80211.h>
#include <wl_cfgp2p.h>
#include <wldev_common.h>
+#include <wl_android.h>
-
-static s8 ioctlbuf[WLC_IOCTL_MAXLEN];
static s8 scanparambuf[WLC_IOCTL_SMLEN];
-static s8 *smbuf = ioctlbuf;
static bool
wl_cfgp2p_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len, const u8 *oui, u32 oui_len, u8 type);
static s32
-wl_cfgp2p_vndr_ie(struct net_device *ndev, s32 bssidx, s32 pktflag,
+wl_cfgp2p_vndr_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx, s32 pktflag,
s8 *oui, s32 ie_id, s8 *data, s32 data_len, s32 delete);
+
+static int wl_cfgp2p_start_xmit(struct sk_buff *skb, struct net_device *ndev);
+static int wl_cfgp2p_do_ioctl(struct net_device *net, struct ifreq *ifr, int cmd);
+static int wl_cfgp2p_if_open(struct net_device *net);
+static int wl_cfgp2p_if_stop(struct net_device *net);
+
+static const struct net_device_ops wl_cfgp2p_if_ops = {
+ .ndo_open = wl_cfgp2p_if_open,
+ .ndo_stop = wl_cfgp2p_if_stop,
+ .ndo_do_ioctl = wl_cfgp2p_do_ioctl,
+ .ndo_start_xmit = wl_cfgp2p_start_xmit,
+};
+
+bool wl_cfgp2p_is_pub_action(void *frame, u32 frame_len)
+{
+ wifi_p2p_pub_act_frame_t *pact_frm;
+
+ if (frame == NULL)
+ return false;
+ pact_frm = (wifi_p2p_pub_act_frame_t *)frame;
+ if (frame_len < sizeof(wifi_p2p_pub_act_frame_t) -1)
+ return false;
+
+ if (pact_frm->category == P2P_PUB_AF_CATEGORY &&
+ pact_frm->action == P2P_PUB_AF_ACTION &&
+ pact_frm->oui_type == P2P_VER &&
+ memcmp(pact_frm->oui, P2P_OUI, sizeof(pact_frm->oui)) == 0) {
+ return true;
+ }
+
+ return false;
+}
+
+bool wl_cfgp2p_is_p2p_action(void *frame, u32 frame_len)
+{
+ wifi_p2p_action_frame_t *act_frm;
+
+ if (frame == NULL)
+ return false;
+ act_frm = (wifi_p2p_action_frame_t *)frame;
+ if (frame_len < sizeof(wifi_p2p_action_frame_t) -1)
+ return false;
+
+ if (act_frm->category == P2P_AF_CATEGORY &&
+ act_frm->type == P2P_VER &&
+ memcmp(act_frm->OUI, P2P_OUI, DOT11_OUI_LEN) == 0) {
+ return true;
+ }
+
+ return false;
+}
+bool wl_cfgp2p_is_gas_action(void *frame, u32 frame_len)
+{
+
+ wifi_p2psd_gas_pub_act_frame_t *sd_act_frm;
+
+ if (frame == NULL)
+ return false;
+
+ sd_act_frm = (wifi_p2psd_gas_pub_act_frame_t *)frame;
+ if (frame_len < sizeof(wifi_p2psd_gas_pub_act_frame_t) - 1)
+ return false;
+ if (sd_act_frm->category != P2PSD_ACTION_CATEGORY)
+ return false;
+
+ if (sd_act_frm->action == P2PSD_ACTION_ID_GAS_IREQ ||
+ sd_act_frm->action == P2PSD_ACTION_ID_GAS_IRESP ||
+ sd_act_frm->action == P2PSD_ACTION_ID_GAS_CREQ ||
+ sd_act_frm->action == P2PSD_ACTION_ID_GAS_CRESP)
+ return true;
+ else
+ return false;
+
+}
+void wl_cfgp2p_print_actframe(bool tx, void *frame, u32 frame_len)
+{
+ wifi_p2p_pub_act_frame_t *pact_frm;
+ wifi_p2p_action_frame_t *act_frm;
+ wifi_p2psd_gas_pub_act_frame_t *sd_act_frm;
+ if (!frame || frame_len <= 2)
+ return;
+
+ if (wl_cfgp2p_is_pub_action(frame, frame_len)) {
+ pact_frm = (wifi_p2p_pub_act_frame_t *)frame;
+ switch (pact_frm->subtype) {
+ case P2P_PAF_GON_REQ:
+ CFGP2P_DBG(("%s P2P Group Owner Negotiation Req Frame\n",
+ (tx)? "TX": "RX"));
+ break;
+ case P2P_PAF_GON_RSP:
+ CFGP2P_DBG(("%s P2P Group Owner Negotiation Rsp Frame\n",
+ (tx)? "TX": "RX"));
+ break;
+ case P2P_PAF_GON_CONF:
+ CFGP2P_DBG(("%s P2P Group Owner Negotiation Confirm Frame\n",
+ (tx)? "TX": "RX"));
+ break;
+ case P2P_PAF_INVITE_REQ:
+ CFGP2P_DBG(("%s P2P Invitation Request Frame\n",
+ (tx)? "TX": "RX"));
+ break;
+ case P2P_PAF_INVITE_RSP:
+ CFGP2P_DBG(("%s P2P Invitation Response Frame\n",
+ (tx)? "TX": "RX"));
+ break;
+ case P2P_PAF_DEVDIS_REQ:
+ CFGP2P_DBG(("%s P2P Device Discoverability Request Frame\n",
+ (tx)? "TX": "RX"));
+ break;
+ case P2P_PAF_DEVDIS_RSP:
+ CFGP2P_DBG(("%s P2P Device Discoverability Response Frame\n",
+ (tx)? "TX": "RX"));
+ break;
+ case P2P_PAF_PROVDIS_REQ:
+ CFGP2P_DBG(("%s P2P Provision Discovery Request Frame\n",
+ (tx)? "TX": "RX"));
+ break;
+ case P2P_PAF_PROVDIS_RSP:
+ CFGP2P_DBG(("%s P2P Provision Discovery Response Frame\n",
+ (tx)? "TX": "RX"));
+ break;
+ default:
+ CFGP2P_DBG(("%s Unknown P2P Public Action Frame\n",
+ (tx)? "TX": "RX"));
+
+ }
+
+ } else if (wl_cfgp2p_is_p2p_action(frame, frame_len)) {
+ act_frm = (wifi_p2p_action_frame_t *)frame;
+ switch (act_frm->subtype) {
+ case P2P_AF_NOTICE_OF_ABSENCE:
+ CFGP2P_DBG(("%s P2P Notice of Absence Frame\n",
+ (tx)? "TX": "RX"));
+ break;
+ case P2P_AF_PRESENCE_REQ:
+ CFGP2P_DBG(("%s P2P Presence Request Frame\n",
+ (tx)? "TX": "RX"));
+ break;
+ case P2P_AF_PRESENCE_RSP:
+ CFGP2P_DBG(("%s P2P Presence Response Frame\n",
+ (tx)? "TX": "RX"));
+ break;
+ case P2P_AF_GO_DISC_REQ:
+ CFGP2P_DBG(("%s P2P Discoverability Request Frame\n",
+ (tx)? "TX": "RX"));
+ break;
+ default:
+ CFGP2P_DBG(("%s Unknown P2P Action Frame\n",
+ (tx)? "TX": "RX"));
+ }
+
+ } else if (wl_cfgp2p_is_gas_action(frame, frame_len)) {
+ sd_act_frm = (wifi_p2psd_gas_pub_act_frame_t *)frame;
+ switch (sd_act_frm->action) {
+ case P2PSD_ACTION_ID_GAS_IREQ:
+ CFGP2P_DBG(("%s P2P GAS Initial Request\n",
+ (tx)? "TX" : "RX"));
+ break;
+ case P2PSD_ACTION_ID_GAS_IRESP:
+ CFGP2P_DBG(("%s P2P GAS Initial Response\n",
+ (tx)? "TX" : "RX"));
+ break;
+ case P2PSD_ACTION_ID_GAS_CREQ:
+ CFGP2P_DBG(("%s P2P GAS Comback Request\n",
+ (tx)? "TX" : "RX"));
+ break;
+ case P2PSD_ACTION_ID_GAS_CRESP:
+ CFGP2P_DBG(("%s P2P GAS Comback Response\n",
+ (tx)? "TX" : "RX"));
+ break;
+ default:
+ CFGP2P_DBG(("%s Unknown P2P GAS Frame\n",
+ (tx)? "TX" : "RX"));
+ }
+ }
+}
+
/*
* Initialize variables related to P2P
*
@@ -110,6 +282,8 @@
void
wl_cfgp2p_deinit_priv(struct wl_priv *wl)
{
+ CFGP2P_DBG(("In\n"));
+
if (wl->p2p) {
kfree(wl->p2p);
wl->p2p = NULL;
@@ -142,7 +316,7 @@
* firmware for P2P device address
*/
ret = wldev_iovar_setbuf_bsscfg(ndev, "p2p_da_override", &null_eth_addr,
- sizeof(null_eth_addr), ioctlbuf, sizeof(ioctlbuf), 0);
+ sizeof(null_eth_addr), wl->ioctl_buf, WLC_IOCTL_MAXLEN, 0, &wl->ioctl_buf_sync);
if (ret && ret != BCME_UNSUPPORTED) {
CFGP2P_ERR(("failed to update device address\n"));
}
@@ -168,14 +342,14 @@
ifreq.chspec = chspec;
memcpy(ifreq.addr.octet, mac->octet, sizeof(ifreq.addr.octet));
- CFGP2P_INFO(("---wl p2p_ifadd %02x:%02x:%02x:%02x:%02x:%02x %s %u\n",
+ CFGP2P_DBG(("---wl p2p_ifadd %02x:%02x:%02x:%02x:%02x:%02x %s %u\n",
ifreq.addr.octet[0], ifreq.addr.octet[1], ifreq.addr.octet[2],
ifreq.addr.octet[3], ifreq.addr.octet[4], ifreq.addr.octet[5],
(if_type == WL_P2P_IF_GO) ? "go" : "client",
(chspec & WL_CHANSPEC_CHAN_MASK) >> WL_CHANSPEC_CHAN_SHIFT));
err = wldev_iovar_setbuf(ndev, "p2p_ifadd", &ifreq, sizeof(ifreq),
- ioctlbuf, sizeof(ioctlbuf));
+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
return err;
}
@@ -194,7 +368,7 @@
netdev->ifindex, mac->octet[0], mac->octet[1], mac->octet[2],
mac->octet[3], mac->octet[4], mac->octet[5]));
ret = wldev_iovar_setbuf(netdev, "p2p_ifdel", mac, sizeof(*mac),
- ioctlbuf, sizeof(ioctlbuf));
+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
if (unlikely(ret < 0)) {
printk("'wl p2p_ifdel' error %d\n", ret);
}
@@ -225,7 +399,7 @@
(chspec & WL_CHANSPEC_CHAN_MASK) >> WL_CHANSPEC_CHAN_SHIFT));
err = wldev_iovar_setbuf(netdev, "p2p_ifupd", &ifreq, sizeof(ifreq),
- ioctlbuf, sizeof(ioctlbuf));
+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
if (unlikely(err < 0)) {
printk("'wl p2p_ifupd' error %d\n", err);
@@ -251,8 +425,8 @@
mac->octet[0], mac->octet[1], mac->octet[2],
mac->octet[3], mac->octet[4], mac->octet[5]));
- ret = wldev_iovar_getbuf_bsscfg(dev, "p2p_if", mac, sizeof(*mac),
- getbuf, sizeof(getbuf), wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_PRIMARY));
+ ret = wldev_iovar_getbuf_bsscfg(dev, "p2p_if", mac, sizeof(*mac), getbuf,
+ sizeof(getbuf), wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_PRIMARY), NULL);
if (ret == 0) {
memcpy(index, getbuf, sizeof(index));
@@ -262,7 +436,7 @@
return ret;
}
-s32
+static s32
wl_cfgp2p_set_discovery(struct wl_priv *wl, s32 on)
{
s32 ret = BCME_OK;
@@ -311,13 +485,14 @@
discovery_mode.chspec = CH20MHZ_CHSPEC(channel);
discovery_mode.dwell = listen_ms;
ret = wldev_iovar_setbuf_bsscfg(dev, "p2p_state", &discovery_mode,
- sizeof(discovery_mode), ioctlbuf, sizeof(ioctlbuf), bssidx);
+ sizeof(discovery_mode), wl->ioctl_buf, WLC_IOCTL_MAXLEN,
+ bssidx, &wl->ioctl_buf_sync);
return ret;
}
/* Get the index of the P2P Discovery BSS */
-s32
+static s32
wl_cfgp2p_get_disc_idx(struct wl_priv *wl, s32 *index)
{
s32 ret;
@@ -381,7 +556,7 @@
* @wl : wl_private data
* Returns 0 if succes
*/
-s32
+static s32
wl_cfgp2p_deinit_discovery(struct wl_priv *wl)
{
s32 ret = BCME_OK;
@@ -419,7 +594,8 @@
* Returns 0 if success.
*/
s32
-wl_cfgp2p_enable_discovery(struct wl_priv *wl, struct net_device *dev, const u8 *ie, u32 ie_len)
+wl_cfgp2p_enable_discovery(struct wl_priv *wl, struct net_device *dev,
+ const u8 *ie, u32 ie_len)
{
s32 ret = BCME_OK;
if (wl_get_p2p_status(wl, DISCOVERY_ON)) {
@@ -511,9 +687,9 @@
wl_escan_params_t *eparams;
wlc_ssid_t ssid;
/* Scan parameters */
-#define P2PAPI_SCAN_NPROBES 4
-#define P2PAPI_SCAN_DWELL_TIME_MS 80
-#define P2PAPI_SCAN_SOCIAL_DWELL_TIME_MS 100
+#define P2PAPI_SCAN_NPROBES 1
+#define P2PAPI_SCAN_DWELL_TIME_MS 50
+#define P2PAPI_SCAN_SOCIAL_DWELL_TIME_MS 40
#define P2PAPI_SCAN_HOME_TIME_MS 10
struct net_device *pri_dev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_PRIMARY);
wl_set_p2p_status(wl, SCANNING);
@@ -530,7 +706,7 @@
return -1;
}
memset(memblk, 0, memsize);
- memset(ioctlbuf, 0, sizeof(ioctlbuf));
+ memset(wl->ioctl_buf, 0, WLC_IOCTL_MAXLEN);
if (search_state == WL_P2P_DISC_ST_SEARCH) {
/*
* If we in SEARCH STATE, we don't need to set SSID explictly
@@ -569,7 +745,7 @@
eparams->params.nprobes = htod32(P2PAPI_SCAN_NPROBES);
eparams->params.home_time = htod32(P2PAPI_SCAN_HOME_TIME_MS);
- if (wl_get_drv_status(wl, CONNECTED))
+ if (wl_get_drv_status_all(wl, CONNECTED))
eparams->params.active_time = htod32(-1);
else if (num_chans == 3)
eparams->params.active_time = htod32(P2PAPI_SCAN_SOCIAL_DWELL_TIME_MS);
@@ -595,9 +771,54 @@
CFGP2P_INFO(("\n"));
ret = wldev_iovar_setbuf_bsscfg(pri_dev, "p2p_scan",
- memblk, memsize, smbuf, sizeof(ioctlbuf), bssidx);
+ memblk, memsize, wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
return ret;
}
+
+/* search function to reach at common channel to send action frame
+ * Parameters:
+ * @wl : wl_private data
+ * @ndev : net device for bssidx
+ * @bssidx : bssidx for BSS
+ * Returns 0 if success.
+ */
+s32
+wl_cfgp2p_act_frm_search(struct wl_priv *wl, struct net_device *ndev,
+ s32 bssidx, s32 channel)
+{
+ s32 ret = 0;
+ u32 chan_cnt = 0;
+ u16 *default_chan_list = NULL;
+ if (!p2p_is_on(wl))
+ return -BCME_ERROR;
+ CFGP2P_ERR((" Enter\n"));
+ if (bssidx == P2PAPI_BSSCFG_PRIMARY)
+ bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE);
+ if (channel)
+ chan_cnt = 1;
+ else
+ chan_cnt = SOCIAL_CHAN_CNT;
+ default_chan_list = kzalloc(chan_cnt * sizeof(*default_chan_list), GFP_KERNEL);
+ if (default_chan_list == NULL) {
+ CFGP2P_ERR(("channel list allocation failed \n"));
+ ret = -ENOMEM;
+ goto exit;
+ }
+ if (channel) {
+ default_chan_list[0] = channel;
+ } else {
+ default_chan_list[0] = SOCIAL_CHAN_1;
+ default_chan_list[1] = SOCIAL_CHAN_2;
+ default_chan_list[2] = SOCIAL_CHAN_3;
+ }
+ ret = wl_cfgp2p_escan(wl, ndev, true, SOCIAL_CHAN_CNT,
+ default_chan_list, WL_P2P_DISC_ST_SEARCH,
+ WL_SCAN_ACTION_START, bssidx);
+ kfree(default_chan_list);
+exit:
+ return ret;
+}
+
/* Check whether pointed-to IE looks like WPA. */
#define wl_cfgp2p_is_wpa_ie(ie, tlvs, len) wl_cfgp2p_has_ie(ie, tlvs, len, \
(const uint8 *)WPS_OUI, WPS_OUI_LEN, WPA_OUI_TYPE)
@@ -635,7 +856,7 @@
u8 delete = 0;
#define IE_TYPE(type, bsstype) (wl_to_p2p_bss_saved_ie(wl, bsstype).p2p_ ## type ## _ie)
#define IE_TYPE_LEN(type, bsstype) (wl_to_p2p_bss_saved_ie(wl, bsstype).p2p_ ## type ## _ie_len)
- if (wl->p2p_supported && p2p_on(wl) && bssidx != -1) {
+ if (p2p_is_on(wl) && bssidx != -1) {
if (bssidx == P2PAPI_BSSCFG_PRIMARY)
bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE);
switch (pktflag) {
@@ -670,7 +891,7 @@
CFGP2P_ERR(("not suitable type\n"));
return -1;
}
- } else if (get_mode_by_netdev(wl, ndev) == WL_MODE_AP) {
+ } else if (wl_get_mode_by_netdev(wl, ndev) == WL_MODE_AP) {
switch (pktflag) {
case VNDR_IE_PRBRSP_FLAG :
mgmt_ie_buf = wl->ap_info->probe_res_ie;
@@ -689,7 +910,7 @@
return -1;
}
bssidx = 0;
- } else if (bssidx == -1 && get_mode_by_netdev(wl, ndev) == WL_MODE_BSS) {
+ } else if (bssidx == -1 && wl_get_mode_by_netdev(wl, ndev) == WL_MODE_BSS) {
switch (pktflag) {
case VNDR_IE_PRBREQ_FLAG :
mgmt_ie_buf = wl->sta_info->probe_req_ie;
@@ -735,8 +956,9 @@
CFGP2P_INFO(("DELELED ID : %d, Len : %d , OUI :"
"%02x:%02x:%02x\n", ie_id, ie_len, ie_buf[pos],
ie_buf[pos+1], ie_buf[pos+2]));
- ret = wl_cfgp2p_vndr_ie(ndev, bssidx, pktflag, ie_buf+pos,
- VNDR_SPEC_ELEMENT_ID, ie_buf+pos+3, ie_len-3, delete);
+ ret = wl_cfgp2p_vndr_ie(wl, ndev, bssidx, pktflag,
+ ie_buf+pos, VNDR_SPEC_ELEMENT_ID, ie_buf+pos+3,
+ ie_len-3, delete);
}
pos += ie_len;
}
@@ -760,8 +982,9 @@
CFGP2P_INFO(("ADDED ID : %d, Len : %d , OUI :"
"%02x:%02x:%02x\n", ie_id, ie_len, ie_buf[pos],
ie_buf[pos+1], ie_buf[pos+2]));
- ret = wl_cfgp2p_vndr_ie(ndev, bssidx, pktflag, ie_buf+pos,
- VNDR_SPEC_ELEMENT_ID, ie_buf+pos+3, ie_len-3, delete);
+ ret = wl_cfgp2p_vndr_ie(wl, ndev, bssidx, pktflag,
+ ie_buf+pos, VNDR_SPEC_ELEMENT_ID, ie_buf+pos+3,
+ ie_len-3, delete);
}
pos += ie_len;
}
@@ -867,7 +1090,7 @@
}
static s32
-wl_cfgp2p_vndr_ie(struct net_device *ndev, s32 bssidx, s32 pktflag,
+wl_cfgp2p_vndr_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx, s32 pktflag,
s8 *oui, s32 ie_id, s8 *data, s32 data_len, s32 delete)
{
s32 err = BCME_OK;
@@ -909,7 +1132,7 @@
memcpy(ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.oui, oui, 3);
memcpy(ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.data, data, data_len);
err = wldev_iovar_setbuf_bsscfg(ndev, "vndr_ie", ie_setbuf, buf_len,
- ioctlbuf, sizeof(ioctlbuf), bssidx);
+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
CFGP2P_INFO(("vndr_ie iovar returns %d\n", err));
kfree(ie_setbuf);
@@ -964,7 +1187,7 @@
del_timer_sync(&wl->p2p->listen_timer);
spin_unlock_bh(&wl->p2p->timer_lock);
}
- cfg80211_remain_on_channel_expired(ndev, wl->cache_cookie, &wl->remain_on_chan,
+ cfg80211_remain_on_channel_expired(ndev, wl->last_roc_id, &wl->remain_on_chan,
wl->remain_on_chan_type, GFP_KERNEL);
} else
wl_clr_p2p_status(wl, LISTEN_EXPIRED);
@@ -1093,10 +1316,10 @@
wl_set_p2p_status(wl, ACTION_TX_NOACK);
CFGP2P_ERR(("WLC_E_ACTION_FRAME_COMPLETE : NO ACK\n"));
}
- wake_up_interruptible(&wl->dongle_event_wait);
} else {
CFGP2P_INFO((" WLC_E_ACTION_FRAME_OFFCHAN_COMPLETE is received,"
"status : %d\n", status));
+ wake_up_interruptible(&wl->netif_change_event);
}
return ret;
}
@@ -1126,15 +1349,15 @@
if (bssidx == P2PAPI_BSSCFG_PRIMARY)
bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE);
- ret = wldev_iovar_setbuf_bsscfg(dev, "actframe",
- af_params, sizeof(*af_params), ioctlbuf, sizeof(ioctlbuf), bssidx);
+ ret = wldev_iovar_setbuf_bsscfg(dev, "actframe", af_params, sizeof(*af_params),
+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
if (ret < 0) {
CFGP2P_ERR((" sending action frame is failed\n"));
goto exit;
}
- timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
+ timeout = wait_event_interruptible_timeout(wl->netif_change_event,
(wl_get_p2p_status(wl, ACTION_TX_COMPLETED) || wl_get_p2p_status(wl, ACTION_TX_NOACK)),
msecs_to_jiffies(MAX_WAIT_TIME));
@@ -1243,7 +1466,7 @@
/* Check if the BSS is up */
*(int*)getbuf = -1;
result = wldev_iovar_getbuf_bsscfg(ndev, "bss", &bsscfg_idx,
- sizeof(bsscfg_idx), getbuf, sizeof(getbuf), 0);
+ sizeof(bsscfg_idx), getbuf, sizeof(getbuf), 0, NULL);
if (result != 0) {
CFGP2P_ERR(("'wl bss -C %d' failed: %d\n", bsscfg_idx, result));
CFGP2P_ERR(("NOTE: this ioctl error is normal "
@@ -1260,7 +1483,7 @@
/* Bring up or down a BSS */
s32
-wl_cfgp2p_bss(struct net_device *ndev, s32 bsscfg_idx, s32 up)
+wl_cfgp2p_bss(struct wl_priv *wl, struct net_device *ndev, s32 bsscfg_idx, s32 up)
{
s32 ret = BCME_OK;
s32 val = up ? 1 : 0;
@@ -1274,7 +1497,7 @@
bss_setbuf.val = htod32(val);
CFGP2P_INFO(("---wl bss -C %d %s\n", bsscfg_idx, up ? "up" : "down"));
ret = wldev_iovar_setbuf(ndev, "bss", &bss_setbuf, sizeof(bss_setbuf),
- ioctlbuf, sizeof(ioctlbuf));
+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
if (ret != 0) {
CFGP2P_ERR(("'bss %d' failed with %d\n", up, ret));
@@ -1314,7 +1537,8 @@
return 0;
}
-s32 wl_cfgp2p_set_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, int len)
+s32
+wl_cfgp2p_set_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, int len)
{
s32 ret = -1;
int count, start, duration;
@@ -1330,7 +1554,7 @@
sscanf(buf, "%d %d %d", &count, &start, &duration);
CFGP2P_DBG(("set_p2p_noa count %d start %d duration %d\n",
- count, start, duration));
+ count, start, duration));
if (count != -1)
wl->p2p->noa.desc[0].count = count;
@@ -1374,7 +1598,8 @@
dongle_noa.desc[0].interval = htod32(wl->p2p->noa.desc[0].interval*1000);
ret = wldev_iovar_setbuf(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION),
- "p2p_noa", &dongle_noa, sizeof(dongle_noa), ioctlbuf, sizeof(ioctlbuf));
+ "p2p_noa", &dongle_noa, sizeof(dongle_noa), wl->ioctl_buf, WLC_IOCTL_MAXLEN,
+ &wl->ioctl_buf_sync);
if (ret < 0) {
CFGP2P_ERR(("fw set p2p_noa failed %d\n", ret));
@@ -1386,7 +1611,8 @@
return ret;
}
-s32 wl_cfgp2p_get_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, int buf_len)
+s32
+wl_cfgp2p_get_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, int buf_len)
{
wifi_p2p_noa_desc_t *noa_desc;
int len = 0, i;
@@ -1428,7 +1654,8 @@
return len * 2;
}
-s32 wl_cfgp2p_set_p2p_ps(struct wl_priv *wl, struct net_device *ndev, char* buf, int len)
+s32
+wl_cfgp2p_set_p2p_ps(struct wl_priv *wl, struct net_device *ndev, char* buf, int len)
{
int ps, ctw;
int ret = -1;
@@ -1446,7 +1673,7 @@
wl->p2p->ops.ops = ps;
ret = wldev_iovar_setbuf(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION),
"p2p_ops", &wl->p2p->ops, sizeof(wl->p2p->ops),
- ioctlbuf, sizeof(ioctlbuf));
+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
if (ret < 0) {
CFGP2P_ERR(("fw set p2p_ops failed %d\n", ret));
}
@@ -1467,3 +1694,257 @@
}
return ret;
}
+
+u8 *
+wl_cfgp2p_retreive_p2pattrib(void *buf, u8 element_id)
+{
+ wifi_p2p_ie_t *ie = NULL;
+ u16 len = 0;
+ u8 *subel;
+ u8 subelt_id;
+ u16 subelt_len;
+
+ if (!buf) {
+ WL_ERR(("P2P IE not present"));
+ return 0;
+ }
+
+ ie = (wifi_p2p_ie_t*) buf;
+ len = ie->len;
+
+ /* Point subel to the P2P IE's subelt field.
+ * Subtract the preceding fields (id, len, OUI, oui_type) from the length.
+ */
+ subel = ie->subelts;
+ len -= 4; /* exclude OUI + OUI_TYPE */
+
+ while (len >= 3) {
+ /* attribute id */
+ subelt_id = *subel;
+ subel += 1;
+ len -= 1;
+
+ /* 2-byte little endian */
+ subelt_len = *subel++;
+ subelt_len |= *subel++ << 8;
+
+ len -= 2;
+ len -= subelt_len; /* for the remaining subelt fields */
+
+ if (subelt_id == element_id) {
+ /* This will point to start of subelement attrib after
+ * attribute id & len
+ */
+ return subel;
+ }
+
+ /* Go to next subelement */
+ subel += subelt_len;
+ }
+
+ /* Not Found */
+ return NULL;
+}
+
+#define P2P_GROUP_CAPAB_GO_BIT 0x01
+u8 *
+wl_cfgp2p_retreive_p2p_dev_addr(wl_bss_info_t *bi, u32 bi_length)
+{
+ wifi_p2p_ie_t * p2p_ie = NULL;
+ u8 *capability = NULL;
+ bool p2p_go = 0;
+ u8 *ptr = NULL;
+
+ if (!(p2p_ie = wl_cfgp2p_find_p2pie(((u8 *) bi) + bi->ie_offset, bi->ie_length))) {
+ WL_ERR(("P2P IE not found"));
+ return NULL;
+ }
+
+ if (!(capability = wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_P2P_INFO))) {
+ WL_ERR(("P2P Capability attribute not found"));
+ return NULL;
+ }
+
+ /* Check Group capability for Group Owner bit */
+ p2p_go = capability[1] & P2P_GROUP_CAPAB_GO_BIT;
+ if (!p2p_go) {
+ return bi->BSSID.octet;
+ }
+
+ /* In probe responses, DEVICE INFO attribute will be present */
+ if (!(ptr = wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_DEV_INFO))) {
+ /* If DEVICE_INFO is not found, this might be a beacon frame.
+ * check for DEVICE_ID in the beacon frame.
+ */
+ ptr = wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_DEV_ID);
+ }
+
+ if (!ptr)
+ WL_ERR((" Both DEVICE_ID & DEVICE_INFO attribute not present in P2P IE "));
+
+ return ptr;
+}
+
+s32
+wl_cfgp2p_register_ndev(struct wl_priv *wl)
+{
+ int ret = 0;
+ struct net_device* net = NULL;
+ struct wireless_dev *wdev;
+ uint8 temp_addr[ETHER_ADDR_LEN] = { 0x00, 0x90, 0x4c, 0x33, 0x22, 0x11 };
+
+ /* Allocate etherdev, including space for private structure */
+ if (!(net = alloc_etherdev(sizeof(wl)))) {
+ CFGP2P_ERR(("%s: OOM - alloc_etherdev\n", __FUNCTION__));
+ goto fail;
+ }
+
+ strcpy(net->name, "p2p%d");
+ net->name[IFNAMSIZ - 1] = '\0';
+
+ /* Copy the reference to wl_priv */
+ memcpy((void *)netdev_priv(net), &wl, sizeof(wl));
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31))
+ ASSERT(!net->open);
+ net->do_ioctl = wl_cfgp2p_do_ioctl;
+ net->hard_start_xmit = wl_cfgp2p_start_xmit;
+ net->open = wl_cfgp2p_if_open;
+ net->stop = wl_cfgp2p_if_stop;
+#else
+ ASSERT(!net->netdev_ops);
+ net->netdev_ops = &wl_cfgp2p_if_ops;
+#endif
+
+ /* Register with a dummy MAC addr */
+ memcpy(net->dev_addr, temp_addr, ETHER_ADDR_LEN);
+
+ wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
+ if (unlikely(!wdev)) {
+ WL_ERR(("Could not allocate wireless device\n"));
+ return -ENOMEM;
+ }
+
+ wdev->wiphy = wl->wdev->wiphy;
+
+ wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS);
+
+ net->ieee80211_ptr = wdev;
+
+ SET_NETDEV_DEV(net, wiphy_dev(wdev->wiphy));
+
+ /* Associate p2p0 network interface with new wdev */
+ wdev->netdev = net;
+
+ /* store p2p net ptr for further reference. Note that iflist won't have this
+ * entry as there corresponding firmware interface is a "Hidden" interface.
+ */
+ if (wl->p2p_net) {
+ CFGP2P_ERR(("p2p_net defined already.\n"));
+ return -EINVAL;
+ } else {
+ wl->p2p_wdev = wdev;
+ wl->p2p_net = net;
+ }
+
+ ret = register_netdev(net);
+ if (ret) {
+ CFGP2P_ERR((" register_netdevice failed (%d)\n", ret));
+ goto fail;
+ }
+
+ printk("%s: P2P Interface Registered\n", net->name);
+
+ return ret;
+fail:
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)
+ net->open = NULL;
+#else
+ net->netdev_ops = NULL;
+#endif
+
+ if (net) {
+ unregister_netdev(net);
+ free_netdev(net);
+ }
+
+ return -ENODEV;
+}
+
+s32
+wl_cfgp2p_unregister_ndev(struct wl_priv *wl)
+{
+
+ if (!wl || !wl->p2p_net) {
+ CFGP2P_ERR(("Invalid Ptr\n"));
+ return -EINVAL;
+ }
+
+ unregister_netdev(wl->p2p_net);
+ free_netdev(wl->p2p_net);
+
+ return 0;
+}
+
+static int wl_cfgp2p_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+ CFGP2P_DBG(("(%s) is not used for data operations. Droping the packet. \n", ndev->name));
+ return 0;
+}
+
+static int wl_cfgp2p_do_ioctl(struct net_device *net, struct ifreq *ifr, int cmd)
+{
+ int ret = 0;
+ struct wl_priv *wl = *(struct wl_priv **)netdev_priv(net);
+ struct net_device *ndev = wl_to_prmry_ndev(wl);
+
+ /* There is no ifidx corresponding to p2p0 in our firmware. So we should
+ * not Handle any IOCTL cmds on p2p0 other than ANDROID PRIVATE CMDs.
+ * For Android PRIV CMD handling map it to primary I/F
+ */
+ if (cmd == SIOCDEVPRIVATE+1) {
+ ret = wl_android_priv_cmd(ndev, ifr, cmd);
+
+ } else {
+ CFGP2P_ERR(("%s: IOCTL req 0x%x on p2p0 I/F. Ignoring. \n",
+ __FUNCTION__, cmd));
+ return -1;
+ }
+
+ return ret;
+}
+
+static int wl_cfgp2p_if_open(struct net_device *net)
+{
+ struct wireless_dev *wdev = net->ieee80211_ptr;
+
+ if (!wdev)
+ return -EINVAL;
+
+ /* If suppose F/W download (ifconfig wlan0 up) hasn't been done by now,
+ * do it here. This will make sure that in concurrent mode, supplicant
+ * is not dependent on a particular order of interface initialization.
+ * i.e you may give wpa_supp -iwlan0 -N -ip2p0 or wpa_supp -ip2p0 -N
+ * -iwlan0.
+ */
+ wl_cfg80211_do_driver_init(net);
+
+ wdev->wiphy->interface_modes |= (BIT(NL80211_IFTYPE_P2P_CLIENT)
+ | BIT(NL80211_IFTYPE_P2P_GO));
+
+ return 0;
+}
+
+static int wl_cfgp2p_if_stop(struct net_device *net)
+{
+ struct wireless_dev *wdev = net->ieee80211_ptr;
+
+ if (!wdev)
+ return -EINVAL;
+
+ wdev->wiphy->interface_modes = (wdev->wiphy->interface_modes)
+ & (~(BIT(NL80211_IFTYPE_P2P_CLIENT)|
+ BIT(NL80211_IFTYPE_P2P_GO)));
+ return 0;
+}
diff --git a/drivers/net/wireless/bcmdhd/wl_cfgp2p.h b/drivers/net/wireless/bcmdhd/wl_cfgp2p.h
index 5a69168..1e5b119 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfgp2p.h
+++ b/drivers/net/wireless/bcmdhd/wl_cfgp2p.h
@@ -101,13 +101,13 @@
#define wl_to_p2p_bss_saved_ie(w, type) ((wl)->p2p->bss_idx[type].saved_ie)
#define wl_to_p2p_bss_private(w, type) ((wl)->p2p->bss_idx[type].private_data)
#define wl_to_p2p_bss(wl, type) ((wl)->p2p->bss_idx[type])
-#define wl_get_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0 : test_bit(WLP2P_STATUS_ ## stat, \
+#define wl_get_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0:test_bit(WLP2P_STATUS_ ## stat, \
&(wl)->p2p->status))
-#define wl_set_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? : set_bit(WLP2P_STATUS_ ## stat, \
+#define wl_set_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0:set_bit(WLP2P_STATUS_ ## stat, \
&(wl)->p2p->status))
-#define wl_clr_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? : clear_bit(WLP2P_STATUS_ ## stat, \
+#define wl_clr_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0:clear_bit(WLP2P_STATUS_ ## stat, \
&(wl)->p2p->status))
-#define wl_chg_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? : change_bit(WLP2P_STATUS_ ## stat, \
+#define wl_chg_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0:change_bit(WLP2P_STATUS_ ## stat, \
&(wl)->p2p->status))
#define p2p_on(wl) ((wl)->p2p->on)
#define p2p_scan(wl) ((wl)->p2p->scan)
@@ -140,7 +140,14 @@
} \
} while (0)
-
+extern bool
+wl_cfgp2p_is_pub_action(void *frame, u32 frame_len);
+extern bool
+wl_cfgp2p_is_p2p_action(void *frame, u32 frame_len);
+extern bool
+wl_cfgp2p_is_gas_action(void *frame, u32 frame_len);
+extern void
+wl_cfgp2p_print_actframe(bool tx, void *frame, u32 frame_len);
extern s32
wl_cfgp2p_init_priv(struct wl_priv *wl);
extern void
@@ -172,6 +179,10 @@
u16 *channels,
s32 search_state, u16 action, u32 bssidx);
+extern s32
+wl_cfgp2p_act_frm_search(struct wl_priv *wl, struct net_device *ndev,
+ s32 bssidx, s32 channel);
+
extern wpa_ie_fixed_t *
wl_cfgp2p_find_wpaie(u8 *parse, u32 len);
@@ -217,7 +228,7 @@
wl_cfgp2p_bss_isup(struct net_device *ndev, int bsscfg_idx);
extern s32
-wl_cfgp2p_bss(struct net_device *ndev, s32 bsscfg_idx, s32 up);
+wl_cfgp2p_bss(struct wl_priv *wl, struct net_device *ndev, s32 bsscfg_idx, s32 up);
extern s32
@@ -235,13 +246,36 @@
extern s32
wl_cfgp2p_set_p2p_ps(struct wl_priv *wl, struct net_device *ndev, char* buf, int len);
+extern u8 *
+wl_cfgp2p_retreive_p2pattrib(void *buf, u8 element_id);
+
+extern u8 *
+wl_cfgp2p_retreive_p2p_dev_addr(wl_bss_info_t *bi, u32 bi_length);
+
+extern s32
+wl_cfgp2p_register_ndev(struct wl_priv *wl);
+
+extern s32
+wl_cfgp2p_unregister_ndev(struct wl_priv *wl);
+
/* WiFi Direct */
#define SOCIAL_CHAN_1 1
#define SOCIAL_CHAN_2 6
#define SOCIAL_CHAN_3 11
+#define SOCIAL_CHAN_CNT 3
#define WL_P2P_WILDCARD_SSID "DIRECT-"
#define WL_P2P_WILDCARD_SSID_LEN 7
#define WL_P2P_INTERFACE_PREFIX "p2p"
#define WL_P2P_TEMP_CHAN "11"
+
+
+#define IS_GAS_REQ(frame, len) (wl_cfgp2p_is_gas_action(frame, len) && \
+ ((frame->action == P2PSD_ACTION_ID_GAS_IREQ) || \
+ (frame->action == P2PSD_ACTION_ID_GAS_CREQ)))
+#define IS_P2P_PUB_ACT_REQ(frame, len) (wl_cfgp2p_is_pub_action(frame, len) && \
+ ((frame->subtype == P2P_PAF_GON_REQ) || \
+ (frame->subtype == P2P_PAF_INVITE_REQ) || \
+ (frame->subtype == P2P_PAF_PROVDIS_REQ)))
+#define IS_P2P_SOCIAL(ch) ((ch == SOCIAL_CHAN_1) || (ch == SOCIAL_CHAN_2) || (ch == SOCIAL_CHAN_3))
#define IS_P2P_SSID(ssid) (memcmp(ssid, WL_P2P_WILDCARD_SSID, WL_P2P_WILDCARD_SSID_LEN) == 0)
#endif /* _wl_cfgp2p_h_ */
diff --git a/drivers/net/wireless/bcmdhd/wl_iw.c b/drivers/net/wireless/bcmdhd/wl_iw.c
index ba3cc6c..d09448a 100644
--- a/drivers/net/wireless/bcmdhd/wl_iw.c
+++ b/drivers/net/wireless/bcmdhd/wl_iw.c
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: wl_iw.c,v 1.132.2.18 2011-02-05 01:44:47 Exp $
+ * $Id: wl_iw.c,v 1.132.2.18 2011-02-05 01:44:47 $
*/
#include <wlioctl.h>
@@ -1564,6 +1564,63 @@
net_os_wake_unlock(dev);
return res;
}
+
+static int
+wl_iw_set_pno_setadd(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra
+)
+{
+ int ret = -1;
+ char *tmp_ptr;
+ int size, tmp_size;
+
+ net_os_wake_lock(dev);
+ WL_ERROR(("\n### %s: info->cmd:%x, info->flags:%x, u.data=0x%p, u.len=%d\n",
+ __FUNCTION__, info->cmd, info->flags,
+ wrqu->data.pointer, wrqu->data.length));
+
+ if (g_onoff == G_WLAN_SET_OFF) {
+ WL_TRACE(("%s: driver is not up yet after START\n", __FUNCTION__));
+ goto exit_proc;
+ }
+
+ if (wrqu->data.length <= strlen(PNOSETADD_SET_CMD) + sizeof(cmd_tlv_t)) {
+ WL_ERROR(("%s argument=%d less than %d\n", __FUNCTION__,
+ wrqu->data.length, (int)(strlen(PNOSETADD_SET_CMD) + sizeof(cmd_tlv_t))));
+ goto exit_proc;
+ }
+
+
+ bcopy(PNOSETUP_SET_CMD, extra, strlen(PNOSETUP_SET_CMD));
+
+ tmp_ptr = extra + strlen(PNOSETUP_SET_CMD);
+ size = wrqu->data.length - strlen(PNOSETUP_SET_CMD);
+ tmp_size = size;
+
+ while (*tmp_ptr && tmp_size > 0) {
+ if ((*tmp_ptr == 'S') && (size - tmp_size) >= sizeof(cmd_tlv_t)) {
+ *(tmp_ptr + 1) = ((*(tmp_ptr + 1) - '0') << 4) + (*(tmp_ptr + 2) - '0');
+ memmove(tmp_ptr + 2, tmp_ptr + 3, tmp_size - 3);
+ tmp_size -= 2 + *(tmp_ptr + 1);
+ tmp_ptr += 2 + *(tmp_ptr + 1);
+ size--;
+ } else {
+ tmp_ptr++;
+ tmp_size--;
+ }
+ }
+
+ wrqu->data.length = strlen(PNOSETUP_SET_CMD) + size;
+ ret = wl_iw_set_pno_set(dev, info, wrqu, extra);
+
+exit_proc:
+ net_os_wake_unlock(dev);
+ return ret;
+
+}
#endif
static int
@@ -1626,7 +1683,7 @@
strcpy(extra, flag);
wrqu.data.length = strlen(extra);
wireless_send_event(dev, cmd, &wrqu, extra);
- net_os_wake_lock_timeout_enable(dev, DHD_EVENT_TIMEOUT);
+ net_os_wake_lock_timeout_enable(dev, DHD_EVENT_TIMEOUT_MS);
WL_TRACE(("Send IWEVCUSTOM Event as %s\n", extra));
return 0;
@@ -2567,6 +2624,8 @@
IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
IW_EVENT_CAPA_SET(range->event_capa, IWEVMICHAELMICFAILURE);
+ IW_EVENT_CAPA_SET(range->event_capa, IWEVASSOCREQIE);
+ IW_EVENT_CAPA_SET(range->event_capa, IWEVASSOCRESPIE);
IW_EVENT_CAPA_SET(range->event_capa, IWEVPMKIDCAND);
#endif
@@ -5473,7 +5532,15 @@
switch (paramid) {
case IW_AUTH_WPA_VERSION:
- iw->wpaversion = paramval;
+ if (paramval & IW_AUTH_WPA_VERSION_DISABLED)
+ val = WPA_AUTH_DISABLED;
+ else if (paramval & (IW_AUTH_WPA_VERSION_WPA))
+ val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
+ else if (paramval & IW_AUTH_WPA_VERSION_WPA2)
+ val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
+ WL_ERROR(("%s: %d: setting wpa_auth to 0x%0x\n", __FUNCTION__, __LINE__, val));
+ if ((error = dev_wlc_intvar_set(dev, "wpa_auth", val)))
+ return error;
break;
case IW_AUTH_CIPHER_PAIRWISE:
@@ -5491,7 +5558,27 @@
break;
case IW_AUTH_KEY_MGMT:
- if (paramval & IW_AUTH_KEY_MGMT_PSK) {
+ if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val)))
+ return error;
+
+ if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
+ if (paramval & IW_AUTH_KEY_MGMT_PSK)
+ val = WPA_AUTH_PSK;
+ else
+ val = WPA_AUTH_UNSPECIFIED;
+ if (paramval & 0x04)
+ val |= WPA2_AUTH_FT;
+ }
+ else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
+ if (paramval & IW_AUTH_KEY_MGMT_PSK)
+ val = WPA2_AUTH_PSK;
+ else
+ val = WPA2_AUTH_UNSPECIFIED;
+ if (paramval & 0x04)
+ val |= WPA2_AUTH_FT;
+ }
+
+ else if (paramval & IW_AUTH_KEY_MGMT_PSK) {
if (iw->wpaversion == IW_AUTH_WPA_VERSION_WPA)
val = WPA_AUTH_PSK;
else if (iw->wpaversion == IW_AUTH_WPA_VERSION_WPA2)
@@ -7526,6 +7613,8 @@
ret = wl_iw_set_pno_reset(dev, info, (union iwreq_data *)dwrq, extra);
else if (strnicmp(extra, PNOSETUP_SET_CMD, strlen(PNOSETUP_SET_CMD)) == 0)
ret = wl_iw_set_pno_set(dev, info, (union iwreq_data *)dwrq, extra);
+ else if (strnicmp(extra, PNOSETADD_SET_CMD, strlen(PNOSETADD_SET_CMD)) == 0)
+ ret = wl_iw_set_pno_setadd(dev, info, (union iwreq_data *)dwrq, extra);
else if (strnicmp(extra, PNOENABLE_SET_CMD, strlen(PNOENABLE_SET_CMD)) == 0)
ret = wl_iw_set_pno_enable(dev, info, (union iwreq_data *)dwrq, extra);
#endif
@@ -8251,6 +8340,21 @@
break;
}
+
+ case WLC_E_ASSOC_REQ_IE:
+ cmd = IWEVASSOCREQIE;
+ wrqu.data.length = datalen;
+ if (datalen < sizeof(extra))
+ memcpy(extra, data, datalen);
+ break;
+
+ case WLC_E_ASSOC_RESP_IE:
+ cmd = IWEVASSOCRESPIE;
+ wrqu.data.length = datalen;
+ if (datalen < sizeof(extra))
+ memcpy(extra, data, datalen);
+ break;
+
case WLC_E_PMKID_CACHE: {
if (data)
{
diff --git a/drivers/net/wireless/bcmdhd/wl_iw.h b/drivers/net/wireless/bcmdhd/wl_iw.h
index c0cc14b..faca5f7 100644
--- a/drivers/net/wireless/bcmdhd/wl_iw.h
+++ b/drivers/net/wireless/bcmdhd/wl_iw.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: wl_iw.h,v 1.15.80.6 2010-12-23 01:13:23 Exp $
+ * $Id: wl_iw.h,v 1.15.80.6 2010-12-23 01:13:23 $
*/
@@ -51,9 +51,10 @@
#define PNOSSIDCLR_SET_CMD "PNOSSIDCLR"
#define PNOSETUP_SET_CMD "PNOSETUP "
+#define PNOSETADD_SET_CMD "PNOSETADD"
#define PNOENABLE_SET_CMD "PNOFORCE"
#define PNODEBUG_SET_CMD "PNODEBUG"
-#define TXPOWER_SET_CMD "TXPOWER"
+#define TXPOWER_SET_CMD "TXPOWER"
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
@@ -226,6 +227,18 @@
iwe_stream_add_point(stream, ends, iwe, extra)
#endif
+extern int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled);
+extern int dhd_pno_clean(dhd_pub_t *dhd);
+extern int dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid,
+ ushort scan_fr, int pno_repeat, int pno_freq_expo_max);
+extern int dhd_pno_get_status(dhd_pub_t *dhd);
+extern int dhd_dev_pno_reset(struct net_device *dev);
+extern int dhd_dev_pno_set(struct net_device *dev, wlc_ssid_t* ssids_local,
+ int nssid, ushort scan_fr, int pno_repeat, int pno_freq_expo_max);
+extern int dhd_dev_pno_enable(struct net_device *dev, int pfn_enabled);
+extern int dhd_dev_get_pno_status(struct net_device *dev);
+extern int dhd_get_dtim_skip(dhd_pub_t *dhd);
+
void dhd_bus_country_set(struct net_device *dev, wl_country_t *cspec);
#define PNO_TLV_PREFIX 'S'
diff --git a/drivers/net/wireless/bcmdhd/dhd_linux_mon.c b/drivers/net/wireless/bcmdhd/wl_linux_mon.c
similarity index 91%
rename from drivers/net/wireless/bcmdhd/dhd_linux_mon.c
rename to drivers/net/wireless/bcmdhd/wl_linux_mon.c
index dd9c71f..f44b4b0 100644
--- a/drivers/net/wireless/bcmdhd/dhd_linux_mon.c
+++ b/drivers/net/wireless/bcmdhd/wl_linux_mon.c
@@ -2,13 +2,13 @@
* Broadcom Dongle Host Driver (DHD), Linux monitor network interface
*
* Copyright (C) 1999-2011, Broadcom Corporation
- *
+ *
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
* under the terms of the GNU General Public License version 2 (the "GPL"),
* available at http://www.broadcom.com/licenses/GPLv2.php, with the
* following added to such license:
- *
+ *
* As a special exception, the copyright holders of this software give you
* permission to link this software with independent modules, and to copy and
* distribute the resulting executable under terms of your choice, provided that
@@ -16,12 +16,12 @@
* the license of that module. An independent module is a module which is not
* derived from this software. The special exception does not apply to any
* modifications of the software.
- *
+ *
* Notwithstanding the above, under no circumstances may you combine this
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: dhd_linux_mon.c,v 1.131.2.55 2011-02-09 05:31:56 Exp $
+ * $Id: wl_linux_mon.c 303266 2011-12-16 00:15:23Z $
*/
#include <linux/string.h>
@@ -96,16 +96,30 @@
static struct net_device* lookup_real_netdev(char *name)
{
int i;
+ int len = 0;
int last_name_len = 0;
struct net_device *ndev;
struct net_device *ndev_found = NULL;
- /* We want to find interface "p2p-eth0-0" for monitor interface "mon.p2p-eth0-0", so
- * we skip "eth0" even if "mon.p2p-eth0-0" contains "eth0"
+ /* We need to find interface "p2p-p2p-0" corresponding to monitor interface "mon-p2p-0",
+ * Once mon iface name reaches IFNAMSIZ, it is reset to p2p0-0 and corresponding mon
+ * iface would be mon-p2p0-0.
*/
for (i = 0; i < DHD_MAX_IFS; i++) {
ndev = dhd_idx2net(g_monitor.dhd_pub, i);
- if (ndev && strstr(name, ndev->name)) {
+
+ /* Skip "p2p" and look for "-p2p0-x" in monitor interface name. If it
+ * it matches, then this netdev is the corresponding real_netdev.
+ */
+ if (ndev && strstr(ndev->name, "p2p-p2p0")) {
+ len = strlen("p2p");
+ } else {
+ /* if p2p- is not present, then the IFNAMSIZ have reached and name
+ * would have got reset. In this casse,look for p2p0-x in mon-p2p0-x
+ */
+ len = 0;
+ }
+ if (ndev && strstr(name, (ndev->name + len))) {
if (strlen(ndev->name) > last_name_len) {
ndev_found = ndev;
last_name_len = strlen(ndev->name);
@@ -225,9 +239,10 @@
mon_if = ndev_to_monif(ndev);
if (mon_if == NULL || mon_if->real_ndev == NULL) {
MON_PRINT(" cannot find matched net dev, skip the packet\n");
+ } else {
+ MON_PRINT("enter, if name: %s, matched if name %s\n",
+ ndev->name, mon_if->real_ndev->name);
}
-
- MON_PRINT("enter, if name: %s, matched if name %s\n", ndev->name, mon_if->real_ndev->name);
}
static int dhd_mon_if_change_mac(struct net_device *ndev, void *addr)
@@ -238,9 +253,10 @@
mon_if = ndev_to_monif(ndev);
if (mon_if == NULL || mon_if->real_ndev == NULL) {
MON_PRINT(" cannot find matched net dev, skip the packet\n");
+ } else {
+ MON_PRINT("enter, if name: %s, matched if name %s\n",
+ ndev->name, mon_if->real_ndev->name);
}
-
- MON_PRINT("enter, if name: %s, matched if name %s\n", ndev->name, mon_if->real_ndev->name);
return ret;
}
diff --git a/drivers/net/wireless/bcmdhd/wldev_common.c b/drivers/net/wireless/bcmdhd/wldev_common.c
index bb3eaea..d9a0b93 100644
--- a/drivers/net/wireless/bcmdhd/wldev_common.c
+++ b/drivers/net/wireless/bcmdhd/wldev_common.c
@@ -24,12 +24,13 @@
* $Id: wldev_common.c,v 1.1.4.1.2.14 2011-02-09 01:40:07 $
*/
-#include <linux/module.h>
+#include <osl.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
#include <linux/netdevice.h>
#include <wldev_common.h>
#include <bcmutils.h>
-#include <dhd_dbg.h>
#define htod32(i) i
#define htod16(i) i
@@ -37,6 +38,13 @@
#define dtoh16(i) i
#define htodchanspec(i) i
#define dtohchanspec(i) i
+
+#define WLDEV_ERROR(args) \
+ do { \
+ printk(KERN_ERR "WLDEV-ERROR) %s : ", __func__); \
+ printk args; \
+ } while (0)
+
extern int dhd_ioctl_entry_local(struct net_device *net, wl_ioctl_t *ioc, int cmd);
s32 wldev_ioctl(
@@ -71,26 +79,34 @@
s32 wldev_iovar_getbuf(
struct net_device *dev, s8 *iovar_name,
- void *param, s32 paramlen, void *buf, s32 buflen)
+ void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync)
{
s32 ret = 0;
s32 iovar_len = 0;
-
+ if (buf_sync) {
+ mutex_lock(buf_sync);
+ }
iovar_len = wldev_mkiovar(iovar_name, param, paramlen, buf, buflen);
ret = wldev_ioctl(dev, WLC_GET_VAR, buf, buflen, FALSE);
+ if (buf_sync)
+ mutex_unlock(buf_sync);
return ret;
}
s32 wldev_iovar_setbuf(
struct net_device *dev, s8 *iovar_name,
- void *param, s32 paramlen, void *buf, s32 buflen)
+ void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync)
{
s32 ret = 0;
s32 iovar_len;
-
+ if (buf_sync) {
+ mutex_lock(buf_sync);
+ }
iovar_len = wldev_mkiovar(iovar_name, param, paramlen, buf, buflen);
ret = wldev_ioctl(dev, WLC_SET_VAR, buf, iovar_len, TRUE);
+ if (buf_sync)
+ mutex_unlock(buf_sync);
return ret;
}
@@ -102,7 +118,7 @@
val = htod32(val);
memset(iovar_buf, 0, sizeof(iovar_buf));
return wldev_iovar_setbuf(dev, iovar, &val, sizeof(val), iovar_buf,
- sizeof(iovar_buf));
+ sizeof(iovar_buf), NULL);
}
@@ -114,7 +130,7 @@
memset(iovar_buf, 0, sizeof(iovar_buf));
err = wldev_iovar_getbuf(dev, iovar, pval, sizeof(*pval), iovar_buf,
- sizeof(iovar_buf));
+ sizeof(iovar_buf), NULL);
if (err == 0)
{
memcpy(pval, iovar_buf, sizeof(*pval));
@@ -148,7 +164,7 @@
if (buflen < 0 || iolen > (u32)buflen)
{
- DHD_ERROR(("%s: buffer is too short\n", __FUNCTION__));
+ WLDEV_ERROR(("%s: buffer is too short\n", __FUNCTION__));
return BCME_BUFTOOSHORT;
}
@@ -177,26 +193,37 @@
s32 wldev_iovar_getbuf_bsscfg(
struct net_device *dev, s8 *iovar_name,
- void *param, s32 paramlen, void *buf, s32 buflen, s32 bsscfg_idx)
+ void *param, s32 paramlen, void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync)
{
s32 ret = 0;
s32 iovar_len = 0;
-
+ if (buf_sync) {
+ mutex_lock(buf_sync);
+ }
iovar_len = wldev_mkiovar_bsscfg(iovar_name, param, paramlen, buf, buflen, bsscfg_idx);
ret = wldev_ioctl(dev, WLC_GET_VAR, buf, buflen, FALSE);
+ if (buf_sync) {
+ mutex_unlock(buf_sync);
+ }
return ret;
}
s32 wldev_iovar_setbuf_bsscfg(
struct net_device *dev, s8 *iovar_name,
- void *param, s32 paramlen, void *buf, s32 buflen, s32 bsscfg_idx)
+ void *param, s32 paramlen, void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync)
{
s32 ret = 0;
s32 iovar_len;
-
+ if (buf_sync) {
+ mutex_lock(buf_sync);
+ }
iovar_len = wldev_mkiovar_bsscfg(iovar_name, param, paramlen, buf, buflen, bsscfg_idx);
+
ret = wldev_ioctl(dev, WLC_SET_VAR, buf, iovar_len, TRUE);
+ if (buf_sync) {
+ mutex_unlock(buf_sync);
+ }
return ret;
}
@@ -208,7 +235,7 @@
val = htod32(val);
memset(iovar_buf, 0, sizeof(iovar_buf));
return wldev_iovar_setbuf_bsscfg(dev, iovar, &val, sizeof(val), iovar_buf,
- sizeof(iovar_buf), bssidx);
+ sizeof(iovar_buf), bssidx, NULL);
}
@@ -220,7 +247,7 @@
memset(iovar_buf, 0, sizeof(iovar_buf));
err = wldev_iovar_getbuf_bsscfg(dev, iovar, pval, sizeof(*pval), iovar_buf,
- sizeof(iovar_buf), bssidx);
+ sizeof(iovar_buf), bssidx, NULL);
if (err == 0)
{
memcpy(pval, iovar_buf, sizeof(*pval));
@@ -309,16 +336,16 @@
return error;
error = wldev_iovar_getbuf(dev, "country", &cspec, sizeof(cspec),
- smbuf, sizeof(smbuf));
+ smbuf, sizeof(smbuf), NULL);
if (error < 0)
- DHD_ERROR(("%s: get country failed = %d\n", __FUNCTION__, error));
+ WLDEV_ERROR(("%s: get country failed = %d\n", __FUNCTION__, error));
if ((error < 0) ||
(strncmp(country_code, smbuf, WLC_CNTRY_BUF_SZ) != 0)) {
bzero(&scbval, sizeof(scb_val_t));
error = wldev_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t), 1);
if (error < 0) {
- DHD_ERROR(("%s: set country failed due to Disassoc error %d\n",
+ WLDEV_ERROR(("%s: set country failed due to Disassoc error %d\n",
__FUNCTION__, error));
return error;
}
@@ -328,14 +355,14 @@
memcpy(cspec.ccode, country_code, WLC_CNTRY_BUF_SZ);
get_customized_country_code((char *)&cspec.country_abbrev, &cspec);
error = wldev_iovar_setbuf(dev, "country", &cspec, sizeof(cspec),
- smbuf, sizeof(smbuf));
+ smbuf, sizeof(smbuf), NULL);
if (error < 0) {
- DHD_ERROR(("%s: set country for %s as %s rev %d failed\n",
+ WLDEV_ERROR(("%s: set country for %s as %s rev %d failed\n",
__FUNCTION__, country_code, cspec.ccode, cspec.rev));
return error;
}
dhd_bus_country_set(dev, &cspec);
- DHD_INFO(("%s: set country for %s as %s rev %d\n",
+ WLDEV_ERROR(("%s: set country for %s as %s rev %d\n",
__FUNCTION__, country_code, cspec.ccode, cspec.rev));
return 0;
}
diff --git a/drivers/net/wireless/bcmdhd/wldev_common.h b/drivers/net/wireless/bcmdhd/wldev_common.h
index 4632680..6a1ba15 100644
--- a/drivers/net/wireless/bcmdhd/wldev_common.h
+++ b/drivers/net/wireless/bcmdhd/wldev_common.h
@@ -21,33 +21,33 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: wldev_common.h,v 1.1.4.1.2.14 2011-02-09 01:40:07 Exp $
+ * $Id: wldev_common.h,v 1.1.4.1.2.14 2011-02-09 01:40:07 $
*/
#ifndef __WLDEV_COMMON_H__
#define __WLDEV_COMMON_H__
#include <wlioctl.h>
-/** wl_dev_ioctl - get/set IOCTLs, will call net_device's do_ioctl (or
+/* wl_dev_ioctl - get/set IOCTLs, will call net_device's do_ioctl (or
* netdev_ops->ndo_do_ioctl in new kernels)
* @dev: the net_device handle
*/
s32 wldev_ioctl(
struct net_device *dev, u32 cmd, void *arg, u32 len, u32 set);
-/** Retrieve named IOVARs, this function calls wl_dev_ioctl with
+/** Retrieve named IOVARs, this function calls wl_dev_ioctl with
* WLC_GET_VAR IOCTL code
*/
s32 wldev_iovar_getbuf(
struct net_device *dev, s8 *iovar_name,
- void *param, s32 paramlen, void *buf, s32 buflen);
+ void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync);
/** Set named IOVARs, this function calls wl_dev_ioctl with
* WLC_SET_VAR IOCTL code
*/
s32 wldev_iovar_setbuf(
struct net_device *dev, s8 *iovar_name,
- void *param, s32 paramlen, void *buf, s32 buflen);
+ void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync);
s32 wldev_iovar_setint(
struct net_device *dev, s8 *iovar, s32 val);
@@ -67,15 +67,15 @@
* WLC_GET_VAR IOCTL code
*/
s32 wldev_iovar_getbuf_bsscfg(
- struct net_device *dev, s8 *iovar_name,
- void *param, s32 paramlen, void *buf, s32 buflen, s32 bsscfg_idx);
+ struct net_device *dev, s8 *iovar_name, void *param, s32 paramlen,
+ void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync);
/** Set named and bsscfg indexed IOVARs, this function calls wl_dev_ioctl with
* WLC_SET_VAR IOCTL code
*/
s32 wldev_iovar_setbuf_bsscfg(
- struct net_device *dev, s8 *iovar_name,
- void *param, s32 paramlen, void *buf, s32 buflen, s32 bsscfg_idx);
+ struct net_device *dev, s8 *iovar_name, void *param, s32 paramlen,
+ void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync);
s32 wldev_iovar_getint_bsscfg(
struct net_device *dev, s8 *iovar, s32 *pval, s32 bssidx);
@@ -94,7 +94,7 @@
extern int net_os_set_suspend_disable(struct net_device *dev, int val);
extern int net_os_set_suspend(struct net_device *dev, int val);
extern int wl_iw_parse_ssid_list_tlv(char** list_str, wlc_ssid_t* ssid,
- int max, int *bytes_left);
+ int max, int *bytes_left);
/* Get the link speed from dongle, speed is in kpbs */
int wldev_get_link_speed(struct net_device *dev, int *plink_speed);
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index 01a7df5..b82a155 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -66,7 +66,7 @@
*/
delta = timespec_sub(old_system, old_rtc);
delta_delta = timespec_sub(delta, old_delta);
- if (abs(delta_delta.tv_sec) >= 2) {
+ if (delta_delta.tv_sec < -2 || delta_delta.tv_sec >= 2) {
/*
* if delta_delta is too large, assume time correction
* has occured and set old_delta to the current delta.
@@ -100,9 +100,8 @@
rtc_tm_to_time(&tm, &new_rtc.tv_sec);
new_rtc.tv_nsec = 0;
- if (new_rtc.tv_sec <= old_rtc.tv_sec) {
- if (new_rtc.tv_sec < old_rtc.tv_sec)
- pr_debug("%s: time travel!\n", dev_name(&rtc->dev));
+ if (new_rtc.tv_sec < old_rtc.tv_sec) {
+ pr_debug("%s: time travel!\n", dev_name(&rtc->dev));
return 0;
}
@@ -119,7 +118,8 @@
sleep_time = timespec_sub(sleep_time,
timespec_sub(new_system, old_system));
- timekeeping_inject_sleeptime(&sleep_time);
+ if (sleep_time.tv_sec >= 0)
+ timekeeping_inject_sleeptime(&sleep_time);
return 0;
}
diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c
index 93730ae..2b42d46 100644
--- a/drivers/staging/android/ram_console.c
+++ b/drivers/staging/android/ram_console.c
@@ -143,7 +143,7 @@
static struct console ram_console = {
.name = "ram",
.write = ram_console_write,
- .flags = CON_PRINTBUFFER | CON_ENABLED,
+ .flags = CON_PRINTBUFFER | CON_ENABLED | CON_ANYTIME,
.index = -1,
};
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c
index 042eb4f..ee44846 100644
--- a/drivers/usb/gadget/android.c
+++ b/drivers/usb/gadget/android.c
@@ -116,6 +116,7 @@
struct android_usb_platform_data *pdata;
bool enabled;
+ struct mutex mutex;
bool connected;
bool sw_connected;
struct work_struct work;
@@ -180,8 +181,6 @@
.label = "android",
.unbind = android_unbind_config,
.bConfigurationValue = 1,
- .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
- .bMaxPower = 0xFA, /* 500ma */
};
static void android_work(struct work_struct *data)
@@ -1156,8 +1155,13 @@
struct android_usb_function *f;
char *buff = buf;
+ mutex_lock(&dev->mutex);
+
list_for_each_entry(f, &dev->enabled_functions, enabled_list)
buff += snprintf(buff, PAGE_SIZE, "%s,", f->name);
+
+ mutex_unlock(&dev->mutex);
+
if (buff != buf)
*(buff-1) = '\n';
return buff - buf;
@@ -1172,6 +1176,13 @@
char buf[256], *b;
int err;
+ mutex_lock(&dev->mutex);
+
+ if (dev->enabled) {
+ mutex_unlock(&dev->mutex);
+ return -EBUSY;
+ }
+
INIT_LIST_HEAD(&dev->enabled_functions);
strlcpy(buf, buff, sizeof(buf));
@@ -1186,6 +1197,8 @@
}
}
+ mutex_unlock(&dev->mutex);
+
return size;
}
@@ -1203,6 +1216,8 @@
struct usb_composite_dev *cdev = dev->cdev;
int enabled = 0;
+ mutex_lock(&dev->mutex);
+
sscanf(buff, "%d", &enabled);
if (enabled && !dev->enabled) {
/* update values in composite driver's copy of device descriptor */
@@ -1220,12 +1235,16 @@
dev->enabled = true;
} else if (!enabled && dev->enabled) {
usb_gadget_disconnect(cdev->gadget);
+ /* Cancel pending control requests */
+ usb_ep_dequeue(cdev->gadget->ep0, cdev->req);
usb_remove_config(cdev, &android_config_driver);
dev->enabled = false;
} else {
pr_err("android_usb: already %s\n",
dev->enabled ? "enabled" : "disabled");
}
+
+ mutex_unlock(&dev->mutex);
return size;
}
@@ -1260,9 +1279,9 @@
} \
static ssize_t \
field ## _store(struct device *dev, struct device_attribute *attr, \
- const char *buf, size_t size) \
+ const char *buf, size_t size) \
{ \
- int value; \
+ int value; \
if (sscanf(buf, format_string, &value) == 1) { \
device_desc.field = value; \
return size; \
@@ -1280,7 +1299,7 @@
} \
static ssize_t \
field ## _store(struct device *dev, struct device_attribute *attr, \
- const char *buf, size_t size) \
+ const char *buf, size_t size) \
{ \
if (size >= sizeof(buffer)) return -EINVAL; \
if (sscanf(buf, "%255s", buffer) == 1) { \
@@ -1404,7 +1423,6 @@
device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
}
- usb_gadget_set_selfpowered(gadget);
dev->cdev = cdev;
return 0;
@@ -1570,6 +1588,7 @@
dev->functions = supported_functions;
INIT_LIST_HEAD(&dev->enabled_functions);
INIT_WORK(&dev->work, android_work);
+ mutex_init(&dev->mutex);
ret = android_create_device(dev);
if (ret) {
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
index 4a74dcf..c7a20aa 100644
--- a/drivers/usb/gadget/f_rndis.c
+++ b/drivers/usb/gadget/f_rndis.c
@@ -734,8 +734,6 @@
rndis_deregister(rndis->config);
rndis_exit();
- rndis_string_defs[0].id = 0;
-
if (gadget_is_dualspeed(c->cdev->gadget))
usb_free_descriptors(f->hs_descriptors);
usb_free_descriptors(f->descriptors);
@@ -775,14 +773,14 @@
if (!can_support_rndis(c) || !ethaddr)
return -EINVAL;
+ /* setup RNDIS itself */
+ status = rndis_init();
+ if (status < 0)
+ return status;
+
/* maybe allocate device-global string IDs */
if (rndis_string_defs[0].id == 0) {
- /* ... and setup RNDIS itself */
- status = rndis_init();
- if (status < 0)
- return status;
-
/* control interface label */
status = usb_string_id(c->cdev);
if (status < 0)
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c
index 6cea2e1..bbfbde7 100644
--- a/drivers/usb/gadget/rndis.c
+++ b/drivers/usb/gadget/rndis.c
@@ -159,25 +159,6 @@
#endif /* RNDIS_PM */
};
-/* HACK: copied from net/core/dev.c to replace dev_get_stats since
- * dev_get_stats cannot be called from atomic context */
-static void netdev_stats_to_stats64(struct rtnl_link_stats64 *stats64,
- const struct net_device_stats *netdev_stats)
-{
-#if BITS_PER_LONG == 64
- BUILD_BUG_ON(sizeof(*stats64) != sizeof(*netdev_stats));
- memcpy(stats64, netdev_stats, sizeof(*stats64));
-#else
- size_t i, n = sizeof(*stats64) / sizeof(u64);
- const unsigned long *src = (const unsigned long *)netdev_stats;
- u64 *dst = (u64 *)stats64;
-
- BUILD_BUG_ON(sizeof(*netdev_stats) / sizeof(unsigned long) !=
- sizeof(*stats64) / sizeof(u64));
- for (i = 0; i < n; i++)
- dst[i] = src[i];
-#endif
-}
/* NDIS Functions */
static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf,
@@ -190,7 +171,7 @@
rndis_query_cmplt_type *resp;
struct net_device *net;
struct rtnl_link_stats64 temp;
- struct rtnl_link_stats64 *stats = &temp;
+ const struct rtnl_link_stats64 *stats;
if (!r) return -ENOMEM;
resp = (rndis_query_cmplt_type *)r->buf;
@@ -213,7 +194,7 @@
resp->InformationBufferOffset = cpu_to_le32(16);
net = rndis_per_dev_params[configNr].dev;
- netdev_stats_to_stats64(stats, &net->stats);
+ stats = dev_get_stats(net, &temp);
switch (OID) {
@@ -1166,11 +1147,15 @@
#endif /* CONFIG_USB_GADGET_DEBUG_FILES */
+static bool rndis_initialized;
int rndis_init(void)
{
u8 i;
+ if (rndis_initialized)
+ return 0;
+
for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
#ifdef CONFIG_USB_GADGET_DEBUG_FILES
char name [20];
@@ -1197,6 +1182,7 @@
INIT_LIST_HEAD(&(rndis_per_dev_params[i].resp_queue));
}
+ rndis_initialized = true;
return 0;
}
@@ -1205,7 +1191,13 @@
#ifdef CONFIG_USB_GADGET_DEBUG_FILES
u8 i;
char name[20];
+#endif
+ if (!rndis_initialized)
+ return;
+ rndis_initialized = false;
+
+#ifdef CONFIG_USB_GADGET_DEBUG_FILES
for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
sprintf(name, NAME_TEMPLATE, i);
remove_proc_entry(name, NULL);
diff --git a/fs/proc/base.c b/fs/proc/base.c
index efb3048..1a8d756 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -891,6 +891,10 @@
return ret;
}
+#define mem_write NULL
+
+#ifndef mem_write
+/* This is a security hazard */
static ssize_t mem_write(struct file * file, const char __user *buf,
size_t count, loff_t *ppos)
{
@@ -949,6 +953,7 @@
out_no_task:
return copied;
}
+#endif
loff_t mem_lseek(struct file *file, loff_t offset, int orig)
{
diff --git a/include/linux/input.h b/include/linux/input.h
index b1f7161..6e7d6d9 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -129,6 +129,9 @@
#define EVIOCGRAB _IOW('E', 0x90, int) /* Grab/Release device */
+#define EVIOCGSUSPENDBLOCK _IOR('E', 0x91, int) /* get suspend block enable */
+#define EVIOCSSUSPENDBLOCK _IOW('E', 0x91, int) /* set suspend block enable */
+
/*
* Device properties and quirks
*/
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 342408c..fa58ec6 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -604,6 +604,12 @@
*/
static void __timekeeping_inject_sleeptime(struct timespec *delta)
{
+ if (!timespec_valid(delta)) {
+ printk(KERN_WARNING "__timekeeping_inject_sleeptime: Invalid "
+ "sleep delta value!\n");
+ return;
+ }
+
xtime = timespec_add(xtime, *delta);
wall_to_monotonic = timespec_sub(wall_to_monotonic, *delta);
total_sleep_time = timespec_add(total_sleep_time, *delta);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
old mode 100644
new mode 100755
index 178bdeb..f57113b
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1674,6 +1674,15 @@
hci_conn_check_pending(hdev);
}
+static inline bool is_sco_active(struct hci_dev *hdev)
+{
+ if (hci_conn_hash_lookup_state(hdev, SCO_LINK, BT_CONNECTED) ||
+ (hci_conn_hash_lookup_state(hdev, ESCO_LINK,
+ BT_CONNECTED)))
+ return true;
+ return false;
+}
+
static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_ev_conn_request *ev = (void *) skb->data;
@@ -1719,7 +1728,8 @@
bacpy(&cp.bdaddr, &ev->bdaddr);
- if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
+ if (lmp_rswitch_capable(hdev) && ((mask & HCI_LM_MASTER)
+ || is_sco_active(hdev)))
cp.role = 0x00; /* Become master */
else
cp.role = 0x01; /* Remain slave */
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 379574c..7b0add2 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1759,6 +1759,7 @@
static void restore_regulatory_settings(bool reset_user)
{
char alpha2[2];
+ char world_alpha2[2];
struct reg_beacon *reg_beacon, *btmp;
struct regulatory_request *reg_request, *tmp;
LIST_HEAD(tmp_reg_req_list);
@@ -1809,11 +1810,13 @@
/* First restore to the basic regulatory settings */
cfg80211_regdomain = cfg80211_world_regdom;
+ world_alpha2[0] = cfg80211_regdomain->alpha2[0];
+ world_alpha2[1] = cfg80211_regdomain->alpha2[1];
mutex_unlock(®_mutex);
mutex_unlock(&cfg80211_mutex);
- regulatory_hint_core(cfg80211_regdomain->alpha2);
+ regulatory_hint_core(world_alpha2);
/*
* This restores the ieee80211_regdom module parameter