]> Git Repo - linux.git/commitdiff
Merge tag 'staging-4.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
authorLinus Torvalds <[email protected]>
Sat, 6 May 2017 01:16:23 +0000 (18:16 -0700)
committerLinus Torvalds <[email protected]>
Sat, 6 May 2017 01:16:23 +0000 (18:16 -0700)
Pull staging/IIO updates from Greg KH:
 "Here is the big staging tree update for 4.12-rc1.

  It's a big one, adding about 350k new lines of crap^Wcode, mostly all
  in a big dump of media drivers from Intel. But there's other new
  drivers in here as well, yet-another-wifi driver, new IIO drivers, and
  a new crypto accelerator.

  We also deleted a bunch of stuff, mostly in patch cleanups, but also
  the Android ION code has shrunk a lot, and the Android low memory
  killer driver was finally deleted, much to the celebration of the -mm
  developers.

  All of these have been in linux-next with a few build issues that will
  show up when you merge to your tree"

Merge conflicts in the new rtl8723bs driver (due to the wifi changes
this merge window) handled as per linux-next, courtesy of Stephen
Rothwell.

* tag 'staging-4.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (1182 commits)
  staging: fsl-mc/dpio: add cpu <--> LE conversion for dpaa2_fd
  staging: ks7010: remove line continuations in quoted strings
  staging: vt6656: use tabs instead of spaces
  staging: android: ion: Fix unnecessary initialization of static variable
  staging: media: atomisp: fix range checking on clk_num
  staging: media: atomisp: fix misspelled word in comment
  staging: media: atomisp: kmap() can't fail
  staging: atomisp: remove #ifdef for runtime PM functions
  staging: atomisp: satm include directory is gone
  atomisp: remove some more unused files
  atomisp: remove hmm_load/store/clear indirections
  atomisp: kill off mmgr_free
  atomisp: clean up the hmm init/cleanup indirections
  atomisp: handle allocation calls before init in the hmm layer
  staging: fsl-dpaa2/eth: Add maintainer for Ethernet driver
  staging: fsl-dpaa2/eth: Add TODO file
  staging: fsl-dpaa2/eth: Add trace points
  staging: fsl-dpaa2/eth: Add driver specific stats
  staging: fsl-dpaa2/eth: Add ethtool support
  staging: fsl-dpaa2/eth: Add Freescale DPAA2 Ethernet driver
  ...

16 files changed:
1  2 
.mailmap
MAINTAINERS
arch/powerpc/kvm/book3s_hv_builtin.c
drivers/iio/adc/Kconfig
drivers/iio/adc/Makefile
drivers/media/dvb-frontends/drxk_hard.c
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/android/ion/ion.c
drivers/staging/lustre/lustre/llite/llite_lib.c
drivers/staging/media/Kconfig
drivers/staging/media/Makefile
drivers/staging/most/hdm-usb/hdm_usb.c
drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
include/linux/sched.h

diff --combined .mailmap
index 1d6f4e7280dc67f630b79456b3f1e5a4c0a41343,de0fc5b2551b37cd649c3a0da30f959c4ade7ad6..d2aeb146efed7991391841aff9ab21e567b886ec
+++ b/.mailmap
@@@ -99,8 -99,6 +99,8 @@@ Linas Vepstas <[email protected]
  Linus Lüssing <[email protected]> <[email protected]>
  Linus Lüssing <[email protected]> <[email protected]>
  Mark Brown <[email protected]>
 +Martin Kepplinger <[email protected]> <[email protected]>
 +Martin Kepplinger <[email protected]> <[email protected]>
  Matthieu CASTET <[email protected]>
  Mauro Carvalho Chehab <[email protected]> <[email protected]>
  Mauro Carvalho Chehab <[email protected]> <[email protected]>
@@@ -111,6 -109,7 +111,7 @@@ Mauro Carvalho Chehab <[email protected]
  Mauro Carvalho Chehab <[email protected]> <[email protected]>
  Matt Ranostay <[email protected]> Matthew Ranostay <[email protected]>
  Matt Ranostay <[email protected]> <[email protected]>
+ Matt Ranostay <[email protected]> <[email protected]>
  Mayuresh Janorkar <[email protected]>
  Michael Buesch <[email protected]>
  Michel Dänzer <[email protected]>
diff --combined MAINTAINERS
index 5f1c69f4aecad8b4d34a838f44ba0bf87c494078,4368f67bb2618abe189e7ad4bc2c827a4584ce77..b948dfaaacd965599083d0db81d28b725d76e6e2
@@@ -813,6 -813,7 +813,7 @@@ W: http://wiki.analog.com
  W:    http://ez.analog.com/community/linux-device-drivers
  S:    Supported
  F:    drivers/iio/*/ad*
+ F:    drivers/iio/adc/ltc2497*
  X:    drivers/iio/*/adjd*
  F:    drivers/staging/iio/*/ad*
  F:    drivers/staging/iio/trigger/iio-trig-bfin-timer.c
@@@ -896,19 -897,12 +897,19 @@@ F:      arch/arm64/boot/dts/apm
  APPLIED MICRO (APM) X-GENE SOC ETHERNET DRIVER
  M:    Iyappan Subramanian <[email protected]>
  M:    Keyur Chudgar <[email protected]>
 +M:    Quan Nguyen <[email protected]>
  S:    Supported
  F:    drivers/net/ethernet/apm/xgene/
  F:    drivers/net/phy/mdio-xgene.c
  F:    Documentation/devicetree/bindings/net/apm-xgene-enet.txt
  F:    Documentation/devicetree/bindings/net/apm-xgene-mdio.txt
  
 +APPLIED MICRO (APM) X-GENE SOC ETHERNET (V2) DRIVER
 +M:    Iyappan Subramanian <[email protected]>
 +M:    Keyur Chudgar <[email protected]>
 +S:    Supported
 +F:    drivers/net/ethernet/apm/xgene-v2/
 +
  APPLIED MICRO (APM) X-GENE SOC PMU
  M:    Tai Nguyen <[email protected]>
  S:    Supported
@@@ -983,7 -977,6 +984,7 @@@ F: arch/arm*/include/asm/perf_event.
  F:    drivers/perf/*
  F:    include/linux/perf/arm_pmu.h
  F:    Documentation/devicetree/bindings/arm/pmu.txt
 +F:    Documentation/devicetree/bindings/perf/
  
  ARM PORT
  M:    Russell King <[email protected]>
@@@ -1096,8 -1089,6 +1097,8 @@@ L:      [email protected]
  F:    arch/arm/mach-artpec
  F:    arch/arm/boot/dts/artpec6*
  F:    drivers/clk/axis
 +F:    drivers/pinctrl/pinctrl-artpec*
 +F:    Documentation/devicetree/bindings/pinctrl/axis,artpec6-pinctrl.txt
  
  ARM/ASPEED MACHINE SUPPORT
  M:    Joel Stanley <[email protected]>
@@@ -2234,7 -2225,7 +2235,7 @@@ ATMEL ISI DRIVE
  M:    Ludovic Desroches <[email protected]>
  L:    [email protected]
  S:    Supported
 -F:    drivers/media/platform/soc_camera/atmel-isi.c
 +F:    drivers/media/platform/atmel/atmel-isi.c
  F:    include/media/atmel-isi.h
  
  ATMEL LCDFB DRIVER
@@@ -2337,6 -2328,21 +2338,6 @@@ S:     Maintaine
  F:    drivers/auxdisplay/
  F:    include/linux/cfag12864b.h
  
 -AVR32 ARCHITECTURE
 -M:    Haavard Skinnemoen <[email protected]>
 -M:    Hans-Christian Egtvedt <[email protected]>
 -W:    http://www.atmel.com/products/AVR32/
 -W:    http://mirror.egtvedt.no/avr32linux.org/
 -W:    http://avrfreaks.net/
 -S:    Maintained
 -F:    arch/avr32/
 -
 -AVR32/AT32AP MACHINE SUPPORT
 -M:    Haavard Skinnemoen <[email protected]>
 -M:    Hans-Christian Egtvedt <[email protected]>
 -S:    Maintained
 -F:    arch/avr32/mach-at32ap/
 -
  AX.25 NETWORK LAYER
  M:    Ralf Baechle <[email protected]>
  L:    [email protected]
@@@ -2539,14 -2545,6 +2540,14 @@@ F:    block
  F:    kernel/trace/blktrace.c
  F:    lib/sbitmap.c
  
 +BFQ I/O SCHEDULER
 +M:    Paolo Valente <[email protected]>
 +M:    Jens Axboe <[email protected]>
 +L:    [email protected]
 +S:    Maintained
 +F:    block/bfq-*
 +F:    Documentation/block/bfq-iosched.txt
 +
  BLOCK2MTD DRIVER
  M:    Joern Engel <[email protected]>
  L:    [email protected]
@@@ -2588,26 -2586,12 +2589,26 @@@ F:   include/uapi/linux/if_bonding.
  
  BPF (Safe dynamic programs and tools)
  M:    Alexei Starovoitov <[email protected]>
 +M:    Daniel Borkmann <[email protected]>
  L:    [email protected]
  L:    [email protected]
  S:    Supported
 +F:    arch/x86/net/bpf_jit*
 +F:    Documentation/networking/filter.txt
 +F:    include/linux/bpf*
 +F:    include/linux/filter.h
 +F:    include/uapi/linux/bpf*
 +F:    include/uapi/linux/filter.h
  F:    kernel/bpf/
 -F:    tools/testing/selftests/bpf/
 +F:    kernel/trace/bpf_trace.c
  F:    lib/test_bpf.c
 +F:    net/bpf/
 +F:    net/core/filter.c
 +F:    net/sched/act_bpf.c
 +F:    net/sched/cls_bpf.c
 +F:    samples/bpf/
 +F:    tools/net/bpf*
 +F:    tools/testing/selftests/bpf/
  
  BROADCOM B44 10/100 ETHERNET DRIVER
  M:    Michael Chan <[email protected]>
@@@ -2954,15 -2938,6 +2955,15 @@@ W:    http://www.linux-c6x.org/wiki/index.
  S:    Maintained
  F:    arch/c6x/
  
 +CA8210 IEEE-802.15.4 RADIO DRIVER
 +M:    Harry Morris <[email protected]>
 +M:    [email protected]
 +L:    [email protected]
 +W:    https://github.com/Cascoda/ca8210-linux.git
 +S:    Maintained
 +F:    drivers/net/ieee802154/ca8210.c
 +F:    Documentation/devicetree/bindings/net/ieee802154/ca8210.txt
 +
  CACHEFILES: FS-CACHE BACKEND FOR CACHING ON MOUNTED FILESYSTEMS
  M:    David Howells <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
@@@ -3050,7 -3025,6 +3051,6 @@@ CAPELLA MICROSYSTEMS LIGHT SENSOR DRIVE
  M:    Kevin Tsai <[email protected]>
  S:    Maintained
  F:    drivers/iio/light/cm*
- F:    Documentation/devicetree/bindings/i2c/trivial-admin-guide/devices.rst
  
  CAVIUM THUNDERX2 ARM64 SOC
  M:    Jayachandran C <[email protected]>
@@@ -3067,14 -3041,6 +3067,14 @@@ S:    Supporte
  F:    drivers/i2c/busses/i2c-octeon*
  F:    drivers/i2c/busses/i2c-thunderx*
  
 +CAVIUM MMC DRIVER
 +M:    Jan Glauber <[email protected]>
 +M:    David Daney <[email protected]>
 +M:    Steven J. Hill <[email protected]>
 +W:    http://www.cavium.com
 +S:    Supported
 +F:    drivers/mmc/host/cavium*
 +
  CAVIUM LIQUIDIO NETWORK DRIVER
  M:     Derek Chickles <[email protected]>
  M:     Satanand Burla <[email protected]>
@@@ -3100,7 -3066,7 +3100,7 @@@ F:      drivers/net/ieee802154/cc2520.
  F:    include/linux/spi/cc2520.h
  F:    Documentation/devicetree/bindings/net/ieee802154/cc2520.txt
  
 -CEC DRIVER
 +CEC FRAMEWORK
  M:    Hans Verkuil <[email protected]>
  L:    [email protected]
  T:    git git://linuxtv.org/media_tree.git
@@@ -3109,9 -3075,10 +3109,9 @@@ S:     Supporte
  F:    Documentation/media/kapi/cec-core.rst
  F:    Documentation/media/uapi/cec
  F:    drivers/media/cec/
 -F:    drivers/media/cec-edid.c
  F:    drivers/media/rc/keymaps/rc-cec.c
  F:    include/media/cec.h
 -F:    include/media/cec-edid.h
 +F:    include/media/cec-notifier.h
  F:    include/uapi/linux/cec.h
  F:    include/uapi/linux/cec-funcs.h
  
@@@ -3482,7 -3449,6 +3482,7 @@@ T:      git git://git.kernel.org/pub/scm/lin
  T:    git git://git.linaro.org/people/vireshk/linux.git (For ARM Updates)
  B:    https://bugzilla.kernel.org
  F:    Documentation/cpu-freq/
 +F:    Documentation/devicetree/bindings/cpufreq/
  F:    drivers/cpufreq/
  F:    include/linux/cpufreq.h
  F:    tools/testing/selftests/cpufreq/
@@@ -3886,6 -3852,12 +3886,12 @@@ T:    git git://git.kernel.org/pub/scm/lin
  S:    Maintained
  F:    drivers/usb/dwc3/
  
+ DEVANTECH SRF ULTRASONIC RANGER IIO DRIVER
+ M:    Andreas Klinger <[email protected]>
+ L:    [email protected]
+ S:    Maintained
+ F:    drivers/iio/proximity/srf*.c
  DEVICE COREDUMP (DEV_COREDUMP)
  M:    Johannes Berg <[email protected]>
  L:    [email protected]
@@@ -4131,6 -4103,18 +4137,18 @@@ S:    Maintaine
  F:    drivers/char/dtlk.c
  F:    include/linux/dtlk.h
  
+ DPAA2 DATAPATH I/O (DPIO) DRIVER
+ M:    Roy Pledge <[email protected]>
+ L:    [email protected]
+ S:    Maintained
+ F:    drivers/staging/fsl-mc/bus/dpio
+ DPAA2 ETHERNET DRIVER
+ M:    Ioana Radulescu <[email protected]>
+ L:    [email protected]
+ S:    Maintained
+ F:    drivers/staging/fsl-dpaa2/ethernet
  DPT_I2O SCSI RAID DRIVER
  M:    Adaptec OEM Raid Solutions <[email protected]>
  L:    [email protected]
@@@ -4178,7 -4162,6 +4196,7 @@@ F:      Documentation/devicetree/bindings/vi
  F:    Documentation/gpu/
  F:    include/drm/
  F:    include/uapi/drm/
 +F:    include/linux/vga*
  
  DRM DRIVERS AND MISC GPU PATCHES
  M:    Daniel Vetter <[email protected]>
@@@ -4192,7 -4175,6 +4210,7 @@@ F:      drivers/gpu/vga
  F:    drivers/gpu/drm/*
  F:    include/drm/drm*
  F:    include/uapi/drm/drm*
 +F:    include/linux/vga*
  
  DRM DRIVER FOR AST SERVER GRAPHICS CHIPS
  M:    Dave Airlie <[email protected]>
@@@ -4208,7 -4190,7 +4226,7 @@@ F:      drivers/gpu/drm/bridge
  DRM DRIVER FOR BOCHS VIRTUAL GPU
  M:    Gerd Hoffmann <[email protected]>
  L:    [email protected]
 -T:    git git://git.kraxel.org/linux drm-qemu
 +T:    git git://anongit.freedesktop.org/drm/drm-misc
  S:    Maintained
  F:    drivers/gpu/drm/bochs/
  
@@@ -4216,7 -4198,7 +4234,7 @@@ DRM DRIVER FOR QEMU'S CIRRUS DEVIC
  M:    Dave Airlie <[email protected]>
  M:    Gerd Hoffmann <[email protected]>
  L:    [email protected]
 -T:    git git://git.kraxel.org/linux drm-qemu
 +T:    git git://anongit.freedesktop.org/drm/drm-misc
  S:    Obsolete
  W:    https://www.kraxel.org/blog/2014/10/qemu-using-cirrus-considered-harmful/
  F:    drivers/gpu/drm/cirrus/
@@@ -4273,7 -4255,6 +4291,7 @@@ L:      [email protected]
  S:    Supported
  F:    drivers/gpu/drm/atmel-hlcdc/
  F:    Documentation/devicetree/bindings/drm/atmel/
 +T:    git git://anongit.freedesktop.org/drm/drm-misc
  
  DRM DRIVERS FOR ALLWINNER A10
  M:    Maxime Ripard  <[email protected]>
@@@ -4281,7 -4262,6 +4299,7 @@@ L:      [email protected]
  S:    Supported
  F:    drivers/gpu/drm/sun4i/
  F:    Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux.git
  
  DRM DRIVERS FOR AMLOGIC SOCS
  M:    Neil Armstrong <[email protected]>
@@@ -4291,9 -4271,6 +4309,9 @@@ W:      http://linux-meson.com
  S:    Supported
  F:    drivers/gpu/drm/meson/
  F:    Documentation/devicetree/bindings/display/amlogic,meson-vpu.txt
 +F:    Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.txt
 +F:    Documentation/gpu/meson.rst
 +T:    git git://anongit.freedesktop.org/drm/drm-misc
  
  DRM DRIVERS FOR EXYNOS
  M:    Inki Dae <[email protected]>
@@@ -4418,14 -4395,13 +4436,14 @@@ S:   Supporte
  F:    drivers/gpu/drm/rcar-du/
  F:    drivers/gpu/drm/shmobile/
  F:    include/linux/platform_data/shmob_drm.h
 +F:    Documentation/devicetree/bindings/display/bridge/renesas,dw-hdmi.txt
  F:    Documentation/devicetree/bindings/display/renesas,du.txt
  
  DRM DRIVER FOR QXL VIRTUAL GPU
  M:    Dave Airlie <[email protected]>
  M:    Gerd Hoffmann <[email protected]>
  L:    [email protected]
 -T:    git git://git.kraxel.org/linux drm-qemu
 +T:    git git://anongit.freedesktop.org/drm/drm-misc
  S:    Maintained
  F:    drivers/gpu/drm/qxl/
  F:    include/uapi/drm/qxl_drm.h
@@@ -4436,7 -4412,6 +4454,7 @@@ L:      [email protected]
  S:    Maintained
  F:    drivers/gpu/drm/rockchip/
  F:    Documentation/devicetree/bindings/display/rockchip/
 +T:    git git://anongit.freedesktop.org/drm/drm-misc
  
  DRM DRIVER FOR SAVAGE VIDEO CARDS
  S:    Orphan / Obsolete
@@@ -4452,7 -4427,7 +4470,7 @@@ DRM DRIVERS FOR ST
  M:    Benjamin Gaignard <[email protected]>
  M:    Vincent Abriou <[email protected]>
  L:    [email protected]
 -T:    git http://git.linaro.org/people/benjamin.gaignard/kernel.git
 +T:    git git://anongit.freedesktop.org/drm/drm-misc
  S:    Maintained
  F:    drivers/gpu/drm/sti
  F:    Documentation/devicetree/bindings/display/st,stih4xx.txt
@@@ -4495,7 -4470,6 +4513,7 @@@ S:      Supporte
  F:    drivers/gpu/drm/vc4/
  F:    include/uapi/drm/vc4_drm.h
  F:    Documentation/devicetree/bindings/display/brcm,bcm-vc4.txt
 +T:    git git://anongit.freedesktop.org/drm/drm-misc
  
  DRM DRIVERS FOR TI OMAP
  M:    Tomi Valkeinen <[email protected]>
@@@ -4518,7 -4492,6 +4536,7 @@@ L:      [email protected]
  S:    Maintained
  F:    drivers/gpu/drm/zte/
  F:    Documentation/devicetree/bindings/display/zte,vou.txt
 +T:    git git://anongit.freedesktop.org/drm/drm-misc
  
  DSBR100 USB FM RADIO DRIVER
  M:    Alexey Klimov <[email protected]>
@@@ -4738,7 -4711,6 +4756,7 @@@ L:      [email protected]
  L:    [email protected]
  S:    Supported
  F:    drivers/edac/octeon_edac*
 +F:    drivers/edac/thunderx_edac*
  
  EDAC-E752X
  M:    Mark Gross <[email protected]>
@@@ -5161,6 -5133,7 +5179,6 @@@ F:      include/uapi/linux/firewire*.
  F:    tools/firewire/
  
  FIRMWARE LOADER (request_firmware)
 -M:    Ming Lei <[email protected]>
  M:    Luis R. Rodriguez <[email protected]>
  L:    [email protected]
  S:    Maintained
@@@ -5190,15 -5163,13 +5208,15 @@@ F:   include/linux/ipmi-fru.
  K:    fmc_d.*register
  
  FPGA MANAGER FRAMEWORK
 -M:    Alan Tull <atull@opensource.altera.com>
 +M:    Alan Tull <atull@kernel.org>
  R:    Moritz Fischer <[email protected]>
  L:    [email protected]
  S:    Maintained
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/atull/linux-fpga.git
 +F:    Documentation/fpga/
 +F:    Documentation/devicetree/bindings/fpga/
  F:    drivers/fpga/
 -F:    include/linux/fpga/fpga-mgr.h
 +F:    include/linux/fpga/
  W:    http://www.rocketboards.org
  
  FPU EMULATOR
@@@ -5310,7 -5281,6 +5328,7 @@@ M:      Scott Wood <[email protected]
  L:    [email protected]
  L:    [email protected]
  S:    Maintained
 +F:    Documentation/devicetree/bindings/powerpc/fsl/
  F:    drivers/soc/fsl/
  F:    include/linux/fsl/
  
@@@ -5454,23 -5424,6 +5472,23 @@@ F:    fs/fuse
  F:    include/uapi/linux/fuse.h
  F:    Documentation/filesystems/fuse.txt
  
 +FUTEX SUBSYSTEM
 +M:    Thomas Gleixner <[email protected]>
 +M:    Ingo Molnar <[email protected]>
 +R:    Peter Zijlstra <[email protected]>
 +R:    Darren Hart <[email protected]>
 +L:    [email protected]
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git locking/core
 +S:    Maintained
 +F:    kernel/futex.c
 +F:    kernel/futex_compat.c
 +F:    include/asm-generic/futex.h
 +F:    include/linux/futex.h
 +F:    include/uapi/linux/futex.h
 +F:    tools/testing/selftests/futex/
 +F:    tools/perf/bench/futex*
 +F:    Documentation/*futex*
 +
  FUTURE DOMAIN TMC-16x0 SCSI DRIVER (16-bit)
  M:    Rik Faith <[email protected]>
  L:    [email protected]
@@@ -5913,13 -5866,6 +5931,13 @@@ F:    drivers/block/cciss
  F:    include/linux/cciss_ioctl.h
  F:    include/uapi/linux/cciss_ioctl.h
  
 +OPA-VNIC DRIVER
 +M:    Dennis Dalessandro <[email protected]>
 +M:    Niranjana Vishwanathapura <[email protected]>
 +L:    [email protected]
 +S:    Supported
 +F:    drivers/infiniband/ulp/opa_vnic
 +
  HFI1 DRIVER
  M:    Mike Marciniszyn <[email protected]>
  M:    Dennis Dalessandro <[email protected]>
@@@ -6082,7 -6028,7 +6100,7 @@@ M:      Sebastian Reichel <[email protected]
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-hsi.git
  S:    Maintained
  F:    Documentation/ABI/testing/sysfs-bus-hsi
 -F:    Documentation/device-drivers/serial-interfaces.rst
 +F:    Documentation/driver-api/hsi.rst
  F:    drivers/hsi/
  F:    include/linux/hsi/
  F:    include/uapi/linux/hsi/
@@@ -6288,7 -6234,7 +6306,7 @@@ F:      drivers/crypto/nx/nx_csbcpb.
  F:    drivers/crypto/nx/nx_debugfs.h
  
  IBM Power 842 compression accelerator
 -M:    Dan Streetman <[email protected]>
 +M:    Haren Myneni <[email protected]>
  S:    Supported
  F:    drivers/crypto/nx/Makefile
  F:    drivers/crypto/nx/Kconfig
@@@ -6528,7 -6474,6 +6546,7 @@@ W:      http://www.openfabrics.org
  Q:    http://patchwork.kernel.org/project/linux-rdma/list/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma.git
  S:    Supported
 +F:    Documentation/devicetree/bindings/infiniband/
  F:    Documentation/infiniband/
  F:    drivers/infiniband/
  F:    include/uapi/linux/if_infiniband.h
@@@ -6561,7 -6506,7 +6579,7 @@@ INPUT MULTITOUCH (MT) PROTOCO
  M:    Henrik Rydberg <[email protected]>
  L:    [email protected]
  S:    Odd fixes
 -F:    Documentation/input/multi-touch-protocol.txt
 +F:    Documentation/input/multi-touch-protocol.rst
  F:    drivers/input/input-mt.c
  K:    \b(ABS|SYN)_MT_
  
@@@ -6842,8 -6787,6 +6860,8 @@@ T:      git git://git.kernel.org/pub/scm/lin
  S:    Maintained
  F:    Documentation/devicetree/bindings/iommu/
  F:    drivers/iommu/
 +F:    include/linux/iommu.h
 +F:    include/linux/iova.h
  
  IP MASQUERADING
  M:    Juanjo Ciarlante <[email protected]>
@@@ -7250,7 -7193,6 +7268,7 @@@ S:      Supporte
  F:    Documentation/s390/kvm.txt
  F:    arch/s390/include/asm/kvm*
  F:    arch/s390/kvm/
 +F:    arch/s390/mm/gmap.c
  
  KERNEL VIRTUAL MACHINE (KVM) FOR ARM
  M:    Christoffer Dall <[email protected]>
@@@ -7571,7 -7513,7 +7589,7 @@@ Q:      http://patchwork.ozlabs.org/project/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git
  S:    Supported
  F:    Documentation/ABI/stable/sysfs-firmware-opal-*
 -F:    Documentation/devicetree/bindings/powerpc/opal/
 +F:    Documentation/devicetree/bindings/powerpc/
  F:    Documentation/devicetree/bindings/rtc/rtc-opal.txt
  F:    Documentation/devicetree/bindings/i2c/i2c-opal.txt
  F:    Documentation/powerpc/
@@@ -7787,14 -7729,6 +7805,14 @@@ S:    Maintaine
  F:    Documentation/hwmon/ltc4261
  F:    drivers/hwmon/ltc4261.c
  
 +LTC4306 I2C MULTIPLEXER DRIVER
 +M:    Michael Hennerich <[email protected]>
 +W:    http://ez.analog.com/community/linux-device-drivers
 +L:    [email protected]
 +S:    Supported
 +F:    drivers/i2c/muxes/i2c-mux-ltc4306.c
 +F:    Documentation/devicetree/bindings/i2c/i2c-mux-ltc4306.txt
 +
  LTP (Linux Test Project)
  M:    Mike Frysinger <[email protected]>
  M:    Cyril Hrubis <[email protected]>
@@@ -7941,7 -7875,7 +7959,7 @@@ S:      Maintaine
  F:    drivers/net/ethernet/marvell/mvneta.*
  
  MARVELL MWIFIEX WIRELESS DRIVER
 -M:    Amitkumar Karwar <akarwar@marvell.com>
 +M:    Amitkumar Karwar <amitkarwar@gmail.com>
  M:    Nishant Sarmukadam <[email protected]>
  M:    Ganapathi Bhat <[email protected]>
  M:    Xinming Hu <[email protected]>
@@@ -7960,13 -7894,6 +7978,13 @@@ M:    Nicolas Pitre <[email protected]
  S:    Odd Fixes
  F:    drivers/mmc/host/mvsdio.*
  
 +MARVELL XENON MMC/SD/SDIO HOST CONTROLLER DRIVER
 +M:    Hu Ziji <[email protected]>
 +L:    [email protected]
 +S:    Supported
 +F:    drivers/mmc/host/sdhci-xenon*
 +F:    Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt
 +
  MATROX FRAMEBUFFER DRIVER
  L:    [email protected]
  S:    Orphan
@@@ -8172,7 -8099,6 +8190,7 @@@ W:      https://linuxtv.or
  Q:    http://patchwork.kernel.org/project/linux-media/list/
  T:    git git://linuxtv.org/media_tree.git
  S:    Maintained
 +F:    Documentation/devicetree/bindings/media/
  F:    Documentation/media/
  F:    drivers/media/
  F:    drivers/staging/media/
  S:    Maintained
  F:    drivers/net/ethernet/mediatek/
  
 +MEDIATEK JPEG DRIVER
 +M:    Rick Chang <[email protected]>
 +M:    Bin Liu <[email protected]>
 +S:    Supported
 +F:    drivers/media/platform/mtk-jpeg/
 +F:    Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt
 +
  MEDIATEK MEDIA DRIVER
  M:    Tiffany Lin <[email protected]>
  M:    Andrew-CT Chen <[email protected]>
  S:    Maintained
  F:    drivers/net/wireless/mediatek/mt7601u/
  
 +MEGACHIPS STDPXXXX-GE-B850V3-FW LVDS/DP++ BRIDGES
 +M:    Peter Senna Tschudin <[email protected]>
 +M:    Martin Donnelly <[email protected]>
 +M:    Martyn Welch <[email protected]>
 +S:    Maintained
 +F:    drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
 +F:    Documentation/devicetree/bindings/video/bridge/megachips-stdpxxxx-ge-b850v3-fw.txt
 +
  MEGARAID SCSI/SAS DRIVERS
  M:    Kashyap Desai <[email protected]>
  M:    Sumit Saxena <[email protected]>
@@@ -8794,16 -8705,14 +8812,16 @@@ F:   drivers/net/ethernet/neterion
  NETFILTER
  M:    Pablo Neira Ayuso <[email protected]>
  M:    Jozsef Kadlecsik <[email protected]>
 +M:    Florian Westphal <[email protected]>
  L:    [email protected]
  L:    [email protected]
  W:    http://www.netfilter.org/
  W:    http://www.iptables.org/
 +W:    http://www.nftables.org/
  Q:    http://patchwork.ozlabs.org/project/netfilter-devel/list/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git
 -S:    Supported
 +S:    Maintained
  F:    include/linux/netfilter*
  F:    include/linux/netfilter/
  F:    include/net/netfilter/
@@@ -8870,7 -8779,6 +8888,7 @@@ W:      http://www.linuxfoundation.org/en/Ne
  Q:    http://patchwork.ozlabs.org/project/netdev/list/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git
 +B:    mailto:[email protected]
  S:    Maintained
  F:    net/
  F:    include/net/
@@@ -8911,12 -8819,12 +8929,12 @@@ F:   net/core/flow.
  F:    net/xfrm/
  F:    net/key/
  F:    net/ipv4/xfrm*
 -F:    net/ipv4/esp4.c
 +F:    net/ipv4/esp4*
  F:    net/ipv4/ah4.c
  F:    net/ipv4/ipcomp.c
  F:    net/ipv4/ip_vti.c
  F:    net/ipv6/xfrm*
 -F:    net/ipv6/esp6.c
 +F:    net/ipv6/esp6*
  F:    net/ipv6/ah6.c
  F:    net/ipv6/ipcomp6.c
  F:    net/ipv6/ip6_vti.c
@@@ -8970,6 -8878,8 +8988,6 @@@ S:      Supporte
  F:    drivers/net/ethernet/qlogic/netxen/
  
  NFC SUBSYSTEM
 -M:    Lauro Ramos Venancio <[email protected]>
 -M:    Aloisio Almeida Jr <[email protected]>
  M:    Samuel Ortiz <[email protected]>
  L:    [email protected]
  L:    [email protected] (subscribers-only)
@@@ -9143,6 -9053,7 +9161,6 @@@ F:      drivers/nvme/target/fcloop.
  
  NVMEM FRAMEWORK
  M:    Srinivas Kandagatla <[email protected]>
 -M:    Maxime Ripard <[email protected]>
  S:    Maintained
  F:    drivers/nvmem/
  F:    Documentation/devicetree/bindings/nvmem/
@@@ -9374,20 -9285,12 +9392,20 @@@ M:   Harald Welte <[email protected]
  S:    Maintained
  F:    drivers/char/pcmcia/cm4040_cs.*
  
 +OMNIVISION OV5647 SENSOR DRIVER
 +M:    Ramiro Oliveira <[email protected]>
 +L:    [email protected]
 +T:    git git://linuxtv.org/media_tree.git
 +S:    Maintained
 +F:    drivers/media/i2c/ov5647.c
 +
  OMNIVISION OV7670 SENSOR DRIVER
  M:    Jonathan Corbet <[email protected]>
  L:    [email protected]
  T:    git git://linuxtv.org/media_tree.git
  S:    Maintained
  F:    drivers/media/i2c/ov7670.c
 +F:    Documentation/devicetree/bindings/media/i2c/ov7670.txt
  
  ONENAND FLASH DRIVER
  M:    Kyungmin Park <[email protected]>
@@@ -10031,8 -9934,6 +10049,8 @@@ M:    Krzysztof Kozlowski <[email protected]
  M:    Sylwester Nawrocki <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
  L:    [email protected] (moderated for non-subscribers)
 +Q:    https://patchwork.kernel.org/project/linux-samsung-soc/list/
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git
  S:    Maintained
  F:    drivers/pinctrl/samsung/
  F:    include/dt-bindings/pinctrl/samsung.h
@@@ -10100,6 -10001,7 +10118,6 @@@ F:   drivers/scsi/pmcraid.
  PMC SIERRA PM8001 DRIVER
  M:    Jack Wang <[email protected]>
  M:    [email protected]
 -L:    [email protected]
  L:    [email protected]
  S:    Supported
  F:    drivers/scsi/pm8001/
@@@ -10198,7 -10100,7 +10216,7 @@@ W:   http://sourceforge.net/projects/acce
  PREEMPTIBLE KERNEL
  M:    Robert Love <[email protected]>
  L:    [email protected]
 -W:    ftp://ftp.kernel.org/pub/linux/kernel/people/rml/preempt-kernel
 +W:    https://www.kernel.org/pub/linux/kernel/people/rml/preempt-kernel
  S:    Supported
  F:    Documentation/preempt-locking.txt
  F:    include/linux/preempt.h
@@@ -10335,8 -10237,6 +10353,8 @@@ F:   include/linux/pwm.
  F:    drivers/pwm/
  F:    drivers/video/backlight/pwm_bl.c
  F:    include/linux/pwm_backlight.h
 +F:    drivers/gpio/gpio-mvebu.c
 +F:    Documentation/devicetree/bindings/gpio/gpio-mvebu.txt
  
  PXA2xx/PXA3xx SUPPORT
  M:    Daniel Mack <[email protected]>
  S:    Maintained
  F:    drivers/video/fbdev/aty/aty128fb.c
  
 +RAINSHADOW-CEC DRIVER
 +M:    Hans Verkuil <[email protected]>
 +L:    [email protected]
 +T:    git git://linuxtv.org/media_tree.git
 +S:    Maintained
 +F:    drivers/media/usb/rainshadow-cec/*
 +
  RALINK MIPS ARCHITECTURE
  M:    John Crispin <[email protected]>
  L:    [email protected]
@@@ -10994,16 -10887,6 +11012,16 @@@ W: http://www.ibm.com/developerworks/li
  S:    Supported
  F:    drivers/iommu/s390-iommu.c
  
 +S390 VFIO-CCW DRIVER
 +M:    Cornelia Huck <[email protected]>
 +M:    Dong Jia Shi <[email protected]>
 +L:    [email protected]
 +L:    [email protected]
 +S:    Supported
 +F:    drivers/s390/cio/vfio_ccw*
 +F:    Documentation/s390/vfio-ccw.txt
 +F:    include/uapi/linux/vfio_ccw.h
 +
  S3C24XX SD/MMC Driver
  M:    Ben Dooks <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
  S:    Supported
  F:    sound/soc/samsung/
  
 +SAMSUNG EXYNOS PSEUDO RANDOM NUMBER GENERATOR (RNG) DRIVER
 +M:    Krzysztof Kozlowski <[email protected]>
 +L:    [email protected]
 +L:    [email protected]
 +S:    Maintained
 +F:    drivers/crypto/exynos-rng.c
 +F:    Documentation/devicetree/bindings/rng/samsung,exynos-rng4.txt
 +
  SAMSUNG FRAMEBUFFER DRIVER
  M:    Jingoo Han <[email protected]>
  L:    [email protected]
@@@ -11083,14 -10958,6 +11101,14 @@@ F: Documentation/devicetree/bindings/re
  F:    Documentation/devicetree/bindings/regulator/samsung,s5m*.txt
  F:    Documentation/devicetree/bindings/clock/samsung,s2mps11.txt
  
 +SAMSUNG S5P Security SubSystem (SSS) DRIVER
 +M:    Krzysztof Kozlowski <[email protected]>
 +M:    Vladimir Zapolskiy <[email protected]>
 +L:    [email protected]
 +L:    [email protected]
 +S:    Maintained
 +F:    drivers/crypto/s5p-sss.c
 +
  SAMSUNG S5P/EXYNOS4 SOC SERIES CAMERA SUBSYSTEM DRIVERS
  M:    Kyungmin Park <[email protected]>
  M:    Sylwester Nawrocki <[email protected]>
@@@ -11222,12 -11089,6 +11240,12 @@@ F: include/linux/dma/dw.
  F:    include/linux/platform_data/dma-dw.h
  F:    drivers/dma/dw/
  
 +SYNOPSYS DESIGNWARE ENTERPRISE ETHERNET DRIVER
 +M:    Jie Deng <[email protected]>
 +L:    [email protected]
 +S:    Supported
 +F:    drivers/net/ethernet/synopsys/
 +
  SYNOPSYS DESIGNWARE I2C DRIVER
  M:    Jarkko Nikula <[email protected]>
  R:    Andy Shevchenko <[email protected]>
@@@ -11266,7 -11127,6 +11284,7 @@@ F:   drivers/power/supply/bq27xxx_battery
  TIMEKEEPING, CLOCKSOURCE CORE, NTP, ALARMTIMER
  M:    John Stultz <[email protected]>
  M:    Thomas Gleixner <[email protected]>
 +R:    Stephen Boyd <[email protected]>
  L:    [email protected]
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/core
  S:    Supported
@@@ -11526,11 -11386,11 +11544,11 @@@ S:        Supporte
  F:    drivers/net/ethernet/emulex/benet/
  
  EMULEX ONECONNECT ROCE DRIVER
 -M:    Selvin Xavier <selvin.xavier@avagotech.com>
 -M:    Devesh Sharma <devesh.sharma@avagotech.com>
 +M:    Selvin Xavier <selvin.xavier@broadcom.com>
 +M:    Devesh Sharma <devesh.sharma@broadcom.com>
  L:    [email protected]
 -W:    http://www.emulex.com
 -S:    Supported
 +W:    http://www.broadcom.com
 +S:    Odd Fixes
  F:    drivers/infiniband/hw/ocrdma/
  F:    include/uapi/rdma/ocrdma-abi.h
  
@@@ -12332,19 -12192,12 +12350,19 @@@ F:        Documentation/accounting/taskstats
  F:    include/linux/taskstats*
  F:    kernel/taskstats.c
  
 -TC CLASSIFIER
 +TC subsystem
  M:    Jamal Hadi Salim <[email protected]>
 +M:    Cong Wang <[email protected]>
 +M:    Jiri Pirko <[email protected]>
  L:    [email protected]
  S:    Maintained
  F:    include/net/pkt_cls.h
 +F:    include/net/pkt_sched.h
 +F:    include/net/tc_act/
  F:    include/uapi/linux/pkt_cls.h
 +F:    include/uapi/linux/pkt_sched.h
 +F:    include/uapi/linux/tc_act/
 +F:    include/uapi/linux/tc_ematch/
  F:    net/sched/
  
  TCP LOW PRIORITY MODULE
@@@ -12629,6 -12482,7 +12647,6 @@@ F:   drivers/clk/ti
  F:    include/linux/clk/ti.h
  
  TI ETHERNET SWITCH DRIVER (CPSW)
 -M:    Mugunthan V N <[email protected]>
  R:    Grygorii Strashko <[email protected]>
  L:    [email protected]
  L:    [email protected]
@@@ -13274,15 -13128,6 +13292,15 @@@ F: drivers/usb
  F:    include/linux/usb.h
  F:    include/linux/usb/
  
 +USB TYPEC SUBSYSTEM
 +M:    Heikki Krogerus <[email protected]>
 +L:    [email protected]
 +S:    Maintained
 +F:    Documentation/ABI/testing/sysfs-class-typec
 +F:    Documentation/usb/typec.rst
 +F:    drivers/usb/typec/
 +F:    include/linux/usb/typec.h
 +
  USB UHCI DRIVER
  M:    Alan Stern <[email protected]>
  L:    [email protected]
  S:    Maintained
  F:    drivers/vfio/platform/
  
 +VGA_SWITCHEROO
 +R:    Lukas Wunner <[email protected]>
 +S:    Maintained
 +F:    Documentation/gpu/vga-switcheroo.rst
 +F:    drivers/gpu/vga/vga_switcheroo.c
 +F:    include/linux/vga_switcheroo.h
 +T:    git git://anongit.freedesktop.org/drm/drm-misc
 +
  VIDEOBUF2 FRAMEWORK
  M:    Pawel Osciak <[email protected]>
  M:    Marek Szyprowski <[email protected]>
  S:    Maintained
  F:    include/linux/virtio_vsock.h
  F:    include/uapi/linux/virtio_vsock.h
 +F:    include/uapi/linux/vsockmon.h
 +F:    net/vmw_vsock/af_vsock_tap.c
  F:    net/vmw_vsock/virtio_transport_common.c
  F:    net/vmw_vsock/virtio_transport.c
 +F:    drivers/net/vsockmon.c
  F:    drivers/vhost/vsock.c
  F:    drivers/vhost/vsock.h
  
@@@ -13489,7 -13323,7 +13507,7 @@@ F:   drivers/virtio
  F:    tools/virtio/
  F:    drivers/net/virtio_net.c
  F:    drivers/block/virtio_blk.c
 -F:    include/linux/virtio_*.h
 +F:    include/linux/virtio*.h
  F:    include/uapi/linux/virtio_*.h
  F:    drivers/crypto/virtio/
  
@@@ -13507,7 -13341,7 +13525,7 @@@ M:   David Airlie <[email protected]
  M:    Gerd Hoffmann <[email protected]>
  L:    [email protected]
  L:    [email protected]
 -T:    git git://git.kraxel.org/linux drm-qemu
 +T:    git git://anongit.freedesktop.org/drm/drm-misc
  S:    Maintained
  F:    drivers/gpu/drm/virtio/
  F:    include/uapi/linux/virtio_gpu.h
@@@ -13577,14 -13411,6 +13595,14 @@@ W: https://linuxtv.or
  S:    Maintained
  F:    drivers/media/platform/vivid/*
  
 +VIMC VIRTUAL MEDIA CONTROLLER DRIVER
 +M:    Helen Koike <[email protected]>
 +L:    [email protected]
 +T:    git git://linuxtv.org/media_tree.git
 +W:    https://linuxtv.org
 +S:    Maintained
 +F:    drivers/media/platform/vimc/*
 +
  VLYNQ BUS
  M:    Florian Fainelli <[email protected]>
  L:    [email protected] (subscribers-only)
@@@ -13793,7 -13619,6 +13811,7 @@@ F:   Documentation/hwmon/wm83?
  F:    Documentation/devicetree/bindings/extcon/extcon-arizona.txt
  F:    Documentation/devicetree/bindings/regulator/arizona-regulator.txt
  F:    Documentation/devicetree/bindings/mfd/arizona.txt
 +F:    Documentation/devicetree/bindings/mfd/wm831x.txt
  F:    arch/arm/mach-s3c64xx/mach-crag6410*
  F:    drivers/clk/clk-wm83*.c
  F:    drivers/extcon/extcon-arizona.c
@@@ -13810,14 -13635,12 +13828,14 @@@ F:        drivers/mfd/cs47l24
  F:    drivers/power/supply/wm83*.c
  F:    drivers/rtc/rtc-wm83*.c
  F:    drivers/regulator/wm8*.c
 +F:    drivers/regulator/arizona*
  F:    drivers/video/backlight/wm83*_bl.c
  F:    drivers/watchdog/wm83*_wdt.c
  F:    include/linux/mfd/arizona/
  F:    include/linux/mfd/wm831x/
  F:    include/linux/mfd/wm8350/
  F:    include/linux/mfd/wm8400*
 +F:    include/linux/regulator/arizona*
  F:    include/linux/wm97xx.h
  F:    include/sound/wm????.h
  F:    sound/soc/codecs/arizona.?
@@@ -14017,7 -13840,7 +14035,7 @@@ YEALINK PHONE DRIVE
  M:    Henk Vergonet <[email protected]>
  L:    [email protected]
  S:    Maintained
 -F:    Documentation/input/yealink.txt
 +F:    Documentation/input/yealink.rst
  F:    drivers/input/misc/yealink.*
  
  Z8530 DRIVER FOR AX.25
index a752e29977e05b170f4a3addcdda8cad3a9c099e,b739ff80e979b8564ecc11524e46edb981f200a9..9c71c72e65ce8153d5816d2a75e68285d3d53997
@@@ -23,7 -23,6 +23,7 @@@
  #include <asm/kvm_book3s.h>
  #include <asm/archrandom.h>
  #include <asm/xics.h>
 +#include <asm/xive.h>
  #include <asm/dbell.h>
  #include <asm/cputhreads.h>
  #include <asm/io.h>
@@@ -101,7 -100,8 +101,8 @@@ void __init kvm_cma_reserve(void
                         (unsigned long)selected_size / SZ_1M);
                align_size = HPT_ALIGN_PAGES << PAGE_SHIFT;
                cma_declare_contiguous(0, selected_size, 0, align_size,
-                       KVM_CMA_CHUNK_ORDER - PAGE_SHIFT, false, &kvm_cma);
+                       KVM_CMA_CHUNK_ORDER - PAGE_SHIFT, false, "kvm_cma",
+                       &kvm_cma);
        }
  }
  
@@@ -194,6 -194,12 +195,6 @@@ long kvmppc_h_random(struct kvm_vcpu *v
        return H_HARDWARE;
  }
  
 -static inline void rm_writeb(unsigned long paddr, u8 val)
 -{
 -      __asm__ __volatile__("stbcix %0,0,%1"
 -              : : "r" (val), "r" (paddr) : "memory");
 -}
 -
  /*
   * Send an interrupt or message to another CPU.
   * The caller needs to include any barrier needed to order writes
   */
  void kvmhv_rm_send_ipi(int cpu)
  {
 -      unsigned long xics_phys;
 +      void __iomem *xics_phys;
        unsigned long msg = PPC_DBELL_TYPE(PPC_DBELL_SERVER);
  
        /* On POWER9 we can use msgsnd for any destination cpu. */
                return;
        }
  
 +      /* We should never reach this */
 +      if (WARN_ON_ONCE(xive_enabled()))
 +          return;
 +
        /* Else poke the target with an IPI */
        xics_phys = paca[cpu].kvm_hstate.xics_phys;
        if (xics_phys)
 -              rm_writeb(xics_phys + XICS_MFRR, IPI_PRIORITY);
 +              __raw_rm_writeb(IPI_PRIORITY, xics_phys + XICS_MFRR);
        else
                opal_int_set_mfrr(get_hard_smp_processor_id(cpu), IPI_PRIORITY);
  }
@@@ -385,9 -387,6 +386,9 @@@ long kvmppc_read_intr(void
        long rc;
        bool again;
  
 +      if (xive_enabled())
 +              return 1;
 +
        do {
                again = false;
                rc = kvmppc_read_one_intr(&again);
  
  static long kvmppc_read_one_intr(bool *again)
  {
 -      unsigned long xics_phys;
 +      void __iomem *xics_phys;
        u32 h_xirr;
        __be32 xirr;
        u32 xisr;
        if (!xics_phys)
                rc = opal_int_get_xirr(&xirr, false);
        else
 -              xirr = _lwzcix(xics_phys + XICS_XIRR);
 +              xirr = __raw_rm_readl(xics_phys + XICS_XIRR);
        if (rc < 0)
                return 1;
  
        if (xisr == XICS_IPI) {
                rc = 0;
                if (xics_phys) {
 -                      _stbcix(xics_phys + XICS_MFRR, 0xff);
 -                      _stwcix(xics_phys + XICS_XIRR, xirr);
 +                      __raw_rm_writeb(0xff, xics_phys + XICS_MFRR);
 +                      __raw_rm_writel(xirr, xics_phys + XICS_XIRR);
                } else {
                        opal_int_set_mfrr(hard_smp_processor_id(), 0xff);
                        rc = opal_int_eoi(h_xirr);
                         * we need to resend that IPI, bummer
                         */
                        if (xics_phys)
 -                              _stbcix(xics_phys + XICS_MFRR, IPI_PRIORITY);
 +                              __raw_rm_writeb(IPI_PRIORITY,
 +                                              xics_phys + XICS_MFRR);
                        else
                                opal_int_set_mfrr(hard_smp_processor_id(),
                                                  IPI_PRIORITY);
diff --combined drivers/iio/adc/Kconfig
index ff5ad3be55b405c827c5ba42243aa4d89aabe39f,0b8915298bf1ff8d663b6d66e4c0af7d5ea57d30..401f47b51d83a394c919e13b5e8684116ea22446
@@@ -130,6 -130,17 +130,17 @@@ config AD799
          To compile this driver as a module, choose M here: the module will be
          called ad799x.
  
+ config ASPEED_ADC
+       tristate "Aspeed ADC"
+       depends on ARCH_ASPEED || COMPILE_TEST
+       depends on COMMON_CLK
+       help
+         If you say yes here you get support for the ADC included in Aspeed
+         BMC SoCs.
+         To compile this driver as a module, choose M here: the module will be
+         called aspeed_adc.
  config AT91_ADC
        tristate "Atmel AT91 ADC"
        depends on ARCH_AT91
@@@ -154,16 -165,6 +165,16 @@@ config AT91_SAMA5D2_AD
          To compile this driver as a module, choose M here: the module will be
          called at91-sama5d2_adc.
  
 +config AXP20X_ADC
 +      tristate "X-Powers AXP20X and AXP22X ADC driver"
 +      depends on MFD_AXP20X
 +      help
 +        Say yes here to have support for X-Powers power management IC (PMIC)
 +        AXP20X and AXP22X ADC devices.
 +
 +        To compile this driver as a module, choose M here: the module will be
 +        called axp20x_adc.
 +
  config AXP288_ADC
        tristate "X-Powers AXP288 ADC driver"
        depends on MFD_AXP20X
@@@ -205,6 -206,17 +216,17 @@@ config CC10001_AD
          This driver can also be built as a module. If so, the module will be
          called cc10001_adc.
  
+ config CPCAP_ADC
+       tristate "Motorola CPCAP PMIC ADC driver"
+       depends on MFD_CPCAP
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
+       help
+         Say yes here to build support for Motorola CPCAP PMIC ADC.
+         This driver can also be built as a module. If so, the module will be
+         called cpcap-adc.
  config DA9150_GPADC
        tristate "Dialog DA9150 GPADC driver support"
        depends on MFD_DA9150
@@@ -239,19 -251,6 +261,19 @@@ config EXYNOS_AD
          To compile this driver as a module, choose M here: the module will be
          called exynos_adc.
  
 +config MXS_LRADC_ADC
 +      tristate "Freescale i.MX23/i.MX28 LRADC ADC"
 +      depends on MFD_MXS_LRADC
 +      select IIO_BUFFER
 +      select IIO_TRIGGERED_BUFFER
 +      help
 +        Say yes here to build support for the ADC functions of the
 +        i.MX23/i.MX28 LRADC. This includes general-purpose ADC readings,
 +        battery voltage measurement, and die temperature measurement.
 +
 +        This driver can also be built as a module. If so, the module will be
 +        called mxs-lradc-adc.
 +
  config FSL_MX25_ADC
        tristate "Freescale MX25 ADC driver"
        depends on MFD_MX25_TSADC
@@@ -328,6 -327,18 +350,18 @@@ config LPC18XX_AD
          To compile this driver as a module, choose M here: the module will be
          called lpc18xx_adc.
  
+ config LPC32XX_ADC
+       tristate "NXP LPC32XX ADC"
+       depends on ARCH_LPC32XX || COMPILE_TEST
+       depends on HAS_IOMEM
+       help
+         Say yes here to build support for the integrated ADC inside the
+         LPC32XX SoC. Note that this feature uses the same hardware as the
+         touchscreen driver, so you should either select only one of the two
+         drivers (lpc32xx_adc or lpc32xx_ts) or, in the OpenFirmware case,
+         activate only one via device tree selection.  Provides direct access
+         via sysfs.
  config LTC2485
        tristate "Linear Technology LTC2485 ADC driver"
        depends on I2C
          To compile this driver as a module, choose M here: the module will be
          called ltc2485.
  
+ config LTC2497
+       tristate "Linear Technology LTC2497 ADC driver"
+       depends on I2C
+       help
+         Say yes here to build support for Linear Technology LTC2497
+         16-Bit 8-/16-Channel Delta Sigma ADC.
+         To compile this driver as a module, choose M here: the module will be
+         called ltc2497.
  config MAX1027
        tristate "Maxim max1027 ADC driver"
        depends on SPI
@@@ -358,6 -379,18 +402,18 @@@ config MAX1110
          To compile this driver as a module, choose M here: the module will be
          called max11100.
  
+ config MAX1118
+       tristate "Maxim max1117/max1118/max1119 ADCs driver"
+       depends on SPI
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
+       help
+         Say yes here to build support for Maxim max1117/max1118/max1119
+         8-bit, dual-channel ADCs.
+         To compile this driver as a module, choose M here: the module will be
+         called max1118.
  config MAX1363
        tristate "Maxim max1363 ADC driver"
        depends on I2C
          To compile this driver as a module, choose M here: the module will be
          called max1363.
  
+ config        MAX9611
+       tristate "Maxim max9611/max9612 ADC driver"
+       depends on I2C
+       help
+         Say yes here to build support for Maxim max9611/max9612 current sense
+         amplifier with 12-bits ADC interface.
+         To compile this driver as a module, choose M here: the module will be
+         called max9611.
  config MCP320X
        tristate "Microchip Technology MCP3x01/02/04/08"
        depends on SPI
@@@ -434,6 -477,20 +500,6 @@@ config MESON_SARAD
          To compile this driver as a module, choose M here: the
          module will be called meson_saradc.
  
 -config MXS_LRADC
 -        tristate "Freescale i.MX23/i.MX28 LRADC"
 -        depends on (ARCH_MXS || COMPILE_TEST) && HAS_IOMEM
 -        depends on INPUT
 -        select STMP_DEVICE
 -        select IIO_BUFFER
 -        select IIO_TRIGGERED_BUFFER
 -        help
 -          Say yes here to build support for i.MX23/i.MX28 LRADC convertor
 -          built into these chips.
 -
 -          To compile this driver as a module, choose M here: the
 -          module will be called mxs-lradc.
 -
  config NAU7802
        tristate "Nuvoton NAU7802 ADC driver"
        depends on I2C
@@@ -451,6 -508,20 +517,20 @@@ config PALMAS_GPAD
          is used in smartphones and tablets and supports a 16 channel
          general purpose ADC.
  
+ config QCOM_VADC_COMMON
+       tristate
+ config QCOM_PM8XXX_XOADC
+       tristate "Qualcomm SSBI PM8xxx PMIC XOADCs"
+       depends on MFD_PM8XXX
+       select QCOM_VADC_COMMON
+       help
+         ADC driver for the XOADC portions of the Qualcomm PM8xxx PMICs
+         using SSBI transport: PM8018, PM8038, PM8058, PM8921.
+         To compile this driver as a module, choose M here: the module
+         will be called qcom-pm8xxx-xoadc.
  config QCOM_SPMI_IADC
        tristate "Qualcomm SPMI PMIC current ADC"
        depends on SPMI
@@@ -469,6 -540,7 +549,7 @@@ config QCOM_SPMI_VAD
        tristate "Qualcomm SPMI PMIC voltage ADC"
        depends on SPMI
        select REGMAP_SPMI
+       select QCOM_VADC_COMMON
        help
          This is the IIO Voltage ADC driver for Qualcomm QPNP VADC Chip.
  
@@@ -503,6 -575,17 +584,17 @@@ config ROCKCHIP_SARAD
          To compile this driver as a module, choose M here: the
          module will be called rockchip_saradc.
  
+ config SPEAR_ADC
+       tristate "ST SPEAr ADC"
+       depends on PLAT_SPEAR || COMPILE_TEST
+       depends on HAS_IOMEM
+       help
+         Say yes here to build support for the integrated ADC inside the
+         ST SPEAr SoC. Provides direct access via sysfs.
+         To compile this driver as a module, choose M here: the
+         module will be called spear_adc.
  config STM32_ADC_CORE
        tristate "STMicroelectronics STM32 adc core"
        depends on ARCH_STM32 || COMPILE_TEST
@@@ -532,7 -615,7 +624,7 @@@ config STM32_AD
  
  config STX104
        tristate "Apex Embedded Systems STX104 driver"
-       depends on X86 && ISA_BUS_API
+       depends on PC104 && X86 && ISA_BUS_API
        select GPIOLIB
        help
          Say yes here to build support for the Apex Embedded Systems STX104
          The base port addresses for the devices may be configured via the base
          array module parameter.
  
+ config SUN4I_GPADC
+       tristate "Support for the Allwinner SoCs GPADC"
+       depends on IIO
+       depends on MFD_SUN4I_GPADC || MACH_SUN8I
+       depends on THERMAL || !THERMAL_OF
+       help
+         Say yes here to build support for Allwinner (A10, A13 and A31) SoCs
+         GPADC. This ADC provides 4 channels which can be used as an ADC or as
+         a touchscreen input and one channel for thermal sensor.
+         The thermal sensor slows down ADC readings and can be disabled by
+         disabling CONFIG_THERMAL_OF. However, the thermal sensor should be
+         enabled by default since the SoC temperature is usually more critical
+         than ADC readings.
+         To compile this driver as a module, choose M here: the module will be
+         called sun4i-gpadc-iio.
  config TI_ADC081C
        tristate "Texas Instruments ADC081C/ADC101C/ADC121C family"
        depends on I2C
diff --combined drivers/iio/adc/Makefile
index a01de757f42c506378d34e3d9411b50306a6518e,56e5fabece4ce12d54a3ca9ce8fbb651cf913a29..9339bec4babe95d650a3131192c6e42354340626
@@@ -14,13 -14,14 +14,15 @@@ obj-$(CONFIG_AD7791) += ad7791.
  obj-$(CONFIG_AD7793) += ad7793.o
  obj-$(CONFIG_AD7887) += ad7887.o
  obj-$(CONFIG_AD799X) += ad799x.o
+ obj-$(CONFIG_ASPEED_ADC) += aspeed_adc.o
  obj-$(CONFIG_AT91_ADC) += at91_adc.o
  obj-$(CONFIG_AT91_SAMA5D2_ADC) += at91-sama5d2_adc.o
 +obj-$(CONFIG_AXP20X_ADC) += axp20x_adc.o
  obj-$(CONFIG_AXP288_ADC) += axp288_adc.o
  obj-$(CONFIG_BCM_IPROC_ADC) += bcm_iproc_adc.o
  obj-$(CONFIG_BERLIN2_ADC) += berlin2-adc.o
  obj-$(CONFIG_CC10001_ADC) += cc10001_adc.o
+ obj-$(CONFIG_CPCAP_ADC) += cpcap-adc.o
  obj-$(CONFIG_DA9150_GPADC) += da9150-gpadc.o
  obj-$(CONFIG_ENVELOPE_DETECTOR) += envelope-detector.o
  obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
@@@ -31,23 -32,31 +33,31 @@@ obj-$(CONFIG_IMX7D_ADC) += imx7d_adc.
  obj-$(CONFIG_INA2XX_ADC) += ina2xx-adc.o
  obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
  obj-$(CONFIG_LPC18XX_ADC) += lpc18xx_adc.o
+ obj-$(CONFIG_LPC32XX_ADC) += lpc32xx_adc.o
  obj-$(CONFIG_LTC2485) += ltc2485.o
+ obj-$(CONFIG_LTC2497) += ltc2497.o
  obj-$(CONFIG_MAX1027) += max1027.o
  obj-$(CONFIG_MAX11100) += max11100.o
+ obj-$(CONFIG_MAX1118) += max1118.o
  obj-$(CONFIG_MAX1363) += max1363.o
+ obj-$(CONFIG_MAX9611) += max9611.o
  obj-$(CONFIG_MCP320X) += mcp320x.o
  obj-$(CONFIG_MCP3422) += mcp3422.o
  obj-$(CONFIG_MEDIATEK_MT6577_AUXADC) += mt6577_auxadc.o
  obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o
  obj-$(CONFIG_MESON_SARADC) += meson_saradc.o
 -obj-$(CONFIG_MXS_LRADC) += mxs-lradc.o
 +obj-$(CONFIG_MXS_LRADC_ADC) += mxs-lradc-adc.o
  obj-$(CONFIG_NAU7802) += nau7802.o
  obj-$(CONFIG_PALMAS_GPADC) += palmas_gpadc.o
  obj-$(CONFIG_QCOM_SPMI_IADC) += qcom-spmi-iadc.o
+ obj-$(CONFIG_QCOM_VADC_COMMON) += qcom-vadc-common.o
  obj-$(CONFIG_QCOM_SPMI_VADC) += qcom-spmi-vadc.o
+ obj-$(CONFIG_QCOM_PM8XXX_XOADC) += qcom-pm8xxx-xoadc.o
  obj-$(CONFIG_RCAR_GYRO_ADC) += rcar-gyroadc.o
  obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o
+ obj-$(CONFIG_SPEAR_ADC) += spear_adc.o
  obj-$(CONFIG_STX104) += stx104.o
+ obj-$(CONFIG_SUN4I_GPADC) += sun4i-gpadc-iio.o
  obj-$(CONFIG_STM32_ADC_CORE) += stm32-adc-core.o
  obj-$(CONFIG_STM32_ADC) += stm32-adc.o
  obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
index b5ea9192a341cbf386f95570aa98c754dc4abad5,2fe493768003a2c64372f5050ffe284f957d32f6..050fe34342d3a6fa0afb805afd83cfa1a96ecf64
@@@ -1904,9 -1904,7 +1904,9 @@@ static int get_lock_status(struct drxk_
                status = get_dvbt_lock_status(state, p_lock_status);
                break;
        default:
 -              break;
 +              pr_debug("Unsupported operation mode %d in %s\n",
 +                      state->m_operation_mode, __func__);
 +              return 0;
        }
  error:
        if (status < 0)
@@@ -5285,7 -5283,6 +5285,6 @@@ static int qam_set_symbolrate(struct dr
        /* Select & calculate correct IQM rate */
        adc_frequency = (state->m_sys_clock_freq * 1000) / 3;
        ratesel = 0;
-       /* printk(KERN_DEBUG "drxk: SR %d\n", state->props.symbol_rate); */
        if (state->props.symbol_rate <= 1188750)
                ratesel = 3;
        else if (state->props.symbol_rate <= 2377500)
diff --combined drivers/staging/Kconfig
index b1fc626125aa663ab50d225c08e26e29fd23f919,74ec7ca0cd3b777472589a13dd371294502e1907..268d4e6ef48a641cd04e9647c2a07b1fc24a216e
@@@ -34,6 -34,8 +34,8 @@@ source "drivers/staging/rtl8192u/Kconfi
  
  source "drivers/staging/rtl8192e/Kconfig"
  
+ source "drivers/staging/rtl8723bs/Kconfig"
  source "drivers/staging/rtl8712/Kconfig"
  
  source "drivers/staging/rtl8188eu/Kconfig"
@@@ -92,6 -94,8 +94,8 @@@ source "drivers/staging/fbtft/Kconfig
  
  source "drivers/staging/fsl-mc/Kconfig"
  
+ source "drivers/staging/fsl-dpaa2/Kconfig"
  source "drivers/staging/wilc1000/Kconfig"
  
  source "drivers/staging/most/Kconfig"
@@@ -102,8 -106,6 +106,8 @@@ source "drivers/staging/greybus/Kconfig
  
  source "drivers/staging/vc04_services/Kconfig"
  
- source "drivers/staging/bcm2835-audio/Kconfig"
+ source "drivers/staging/ccree/Kconfig"
  
 +source "drivers/staging/typec/Kconfig"
 +
  endif # STAGING
diff --combined drivers/staging/Makefile
index 682127c20da59cc4680adf530924f57c25c9577a,422fae4ea0f3d1e2e859f3edef977c7f21c89e8b..b93e6f5f0f6eadc21efeda879175969fc68d7f72
@@@ -1,12 -1,12 +1,13 @@@
  # Makefile for staging directory
  
  obj-y                         += media/
 +obj-y                         += typec/
  obj-$(CONFIG_PRISM2_USB)      += wlan-ng/
  obj-$(CONFIG_COMEDI)          += comedi/
  obj-$(CONFIG_FB_OLPC_DCON)    += olpc_dcon/
  obj-$(CONFIG_RTL8192U)                += rtl8192u/
  obj-$(CONFIG_RTL8192E)                += rtl8192e/
+ obj-$(CONFIG_RTL8723BS)               += rtl8723bs/
  obj-$(CONFIG_R8712U)          += rtl8712/
  obj-$(CONFIG_R8188EU)         += rtl8188eu/
  obj-$(CONFIG_RTS5208)         += rts5208/
@@@ -36,9 -36,11 +37,10 @@@ obj-$(CONFIG_UNISYSSPAR)    += unisys
  obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD) += clocking-wizard/
  obj-$(CONFIG_FB_TFT)          += fbtft/
  obj-$(CONFIG_FSL_MC_BUS)      += fsl-mc/
+ obj-$(CONFIG_FSL_DPAA2)               += fsl-dpaa2/
  obj-$(CONFIG_WILC1000)                += wilc1000/
  obj-$(CONFIG_MOST)            += most/
  obj-$(CONFIG_KS7010)          += ks7010/
  obj-$(CONFIG_GREYBUS)         += greybus/
  obj-$(CONFIG_BCM2835_VCHIQ)   += vc04_services/
- obj-$(CONFIG_SND_BCM2835)     += bcm2835-audio/
+ obj-$(CONFIG_CRYPTO_DEV_CCREE)        += ccree/
 -
index 95a7f1648c00cac778a5ca69c023d4d293ce17da,992ee2dd88018a938289509d7594a207d71bf6f8..03d3a4fce0e298a780e75cda87faddbcddc078c2
  #include <linux/sched/task.h>
  
  #include "ion.h"
- #include "ion_priv.h"
- #include "compat_ion.h"
  
- bool ion_buffer_fault_user_mappings(struct ion_buffer *buffer)
- {
-       return (buffer->flags & ION_FLAG_CACHED) &&
-               !(buffer->flags & ION_FLAG_CACHED_NEEDS_SYNC);
- }
+ static struct ion_device *internal_dev;
+ static int heap_id;
  
  bool ion_buffer_cached(struct ion_buffer *buffer)
  {
        return !!(buffer->flags & ION_FLAG_CACHED);
  }
  
- static inline struct page *ion_buffer_page(struct page *page)
- {
-       return (struct page *)((unsigned long)page & ~(1UL));
- }
- static inline bool ion_buffer_page_is_dirty(struct page *page)
- {
-       return !!((unsigned long)page & 1UL);
- }
- static inline void ion_buffer_page_dirty(struct page **page)
- {
-       *page = (struct page *)((unsigned long)(*page) | 1UL);
- }
- static inline void ion_buffer_page_clean(struct page **page)
- {
-       *page = (struct page *)((unsigned long)(*page) & ~(1UL));
- }
  /* this function should only be called while dev->lock is held */
  static void ion_buffer_add(struct ion_device *dev,
                           struct ion_buffer *buffer)
  static struct ion_buffer *ion_buffer_create(struct ion_heap *heap,
                                            struct ion_device *dev,
                                            unsigned long len,
-                                           unsigned long align,
                                            unsigned long flags)
  {
        struct ion_buffer *buffer;
        struct sg_table *table;
-       struct scatterlist *sg;
-       int i, ret;
+       int ret;
  
        buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
        if (!buffer)
  
        buffer->heap = heap;
        buffer->flags = flags;
-       kref_init(&buffer->ref);
  
-       ret = heap->ops->allocate(heap, buffer, len, align, flags);
+       ret = heap->ops->allocate(heap, buffer, len, flags);
  
        if (ret) {
                if (!(heap->flags & ION_HEAP_FLAG_DEFER_FREE))
                        goto err2;
  
                ion_heap_freelist_drain(heap, 0);
-               ret = heap->ops->allocate(heap, buffer, len, align,
-                                         flags);
+               ret = heap->ops->allocate(heap, buffer, len, flags);
                if (ret)
                        goto err2;
        }
        buffer->dev = dev;
        buffer->size = len;
  
-       if (ion_buffer_fault_user_mappings(buffer)) {
-               int num_pages = PAGE_ALIGN(buffer->size) / PAGE_SIZE;
-               struct scatterlist *sg;
-               int i, j, k = 0;
-               buffer->pages = vmalloc(sizeof(struct page *) * num_pages);
-               if (!buffer->pages) {
-                       ret = -ENOMEM;
-                       goto err1;
-               }
-               for_each_sg(table->sgl, sg, table->nents, i) {
-                       struct page *page = sg_page(sg);
-                       for (j = 0; j < sg->length / PAGE_SIZE; j++)
-                               buffer->pages[k++] = page++;
-               }
-       }
        buffer->dev = dev;
        buffer->size = len;
        INIT_LIST_HEAD(&buffer->vmas);
+       INIT_LIST_HEAD(&buffer->attachments);
        mutex_init(&buffer->lock);
-       /*
-        * this will set up dma addresses for the sglist -- it is not
-        * technically correct as per the dma api -- a specific
-        * device isn't really taking ownership here.  However, in practice on
-        * our systems the only dma_address space is physical addresses.
-        * Additionally, we can't afford the overhead of invalidating every
-        * allocation via dma_map_sg. The implicit contract here is that
-        * memory coming from the heaps is ready for dma, ie if it has a
-        * cached mapping that mapping has been invalidated
-        */
-       for_each_sg(buffer->sg_table->sgl, sg, buffer->sg_table->nents, i) {
-               sg_dma_address(sg) = sg_phys(sg);
-               sg_dma_len(sg) = sg->length;
-       }
        mutex_lock(&dev->buffer_lock);
        ion_buffer_add(dev, buffer);
        mutex_unlock(&dev->buffer_lock);
@@@ -200,9 -139,8 +139,8 @@@ void ion_buffer_destroy(struct ion_buff
        kfree(buffer);
  }
  
- static void _ion_buffer_destroy(struct kref *kref)
+ static void _ion_buffer_destroy(struct ion_buffer *buffer)
  {
-       struct ion_buffer *buffer = container_of(kref, struct ion_buffer, ref);
        struct ion_heap *heap = buffer->heap;
        struct ion_device *dev = buffer->dev;
  
                ion_buffer_destroy(buffer);
  }
  
- static void ion_buffer_get(struct ion_buffer *buffer)
- {
-       kref_get(&buffer->ref);
- }
- static int ion_buffer_put(struct ion_buffer *buffer)
- {
-       return kref_put(&buffer->ref, _ion_buffer_destroy);
- }
- static void ion_buffer_add_to_handle(struct ion_buffer *buffer)
- {
-       mutex_lock(&buffer->lock);
-       buffer->handle_count++;
-       mutex_unlock(&buffer->lock);
- }
- static void ion_buffer_remove_from_handle(struct ion_buffer *buffer)
- {
-       /*
-        * when a buffer is removed from a handle, if it is not in
-        * any other handles, copy the taskcomm and the pid of the
-        * process it's being removed from into the buffer.  At this
-        * point there will be no way to track what processes this buffer is
-        * being used by, it only exists as a dma_buf file descriptor.
-        * The taskcomm and pid can provide a debug hint as to where this fd
-        * is in the system
-        */
-       mutex_lock(&buffer->lock);
-       buffer->handle_count--;
-       BUG_ON(buffer->handle_count < 0);
-       if (!buffer->handle_count) {
-               struct task_struct *task;
-               task = current->group_leader;
-               get_task_comm(buffer->task_comm, task);
-               buffer->pid = task_pid_nr(task);
-       }
-       mutex_unlock(&buffer->lock);
- }
- static struct ion_handle *ion_handle_create(struct ion_client *client,
-                                           struct ion_buffer *buffer)
- {
-       struct ion_handle *handle;
-       handle = kzalloc(sizeof(*handle), GFP_KERNEL);
-       if (!handle)
-               return ERR_PTR(-ENOMEM);
-       kref_init(&handle->ref);
-       RB_CLEAR_NODE(&handle->node);
-       handle->client = client;
-       ion_buffer_get(buffer);
-       ion_buffer_add_to_handle(buffer);
-       handle->buffer = buffer;
-       return handle;
- }
- static void ion_handle_kmap_put(struct ion_handle *);
- static void ion_handle_destroy(struct kref *kref)
- {
-       struct ion_handle *handle = container_of(kref, struct ion_handle, ref);
-       struct ion_client *client = handle->client;
-       struct ion_buffer *buffer = handle->buffer;
-       mutex_lock(&buffer->lock);
-       while (handle->kmap_cnt)
-               ion_handle_kmap_put(handle);
-       mutex_unlock(&buffer->lock);
-       idr_remove(&client->idr, handle->id);
-       if (!RB_EMPTY_NODE(&handle->node))
-               rb_erase(&handle->node, &client->handles);
-       ion_buffer_remove_from_handle(buffer);
-       ion_buffer_put(buffer);
-       kfree(handle);
- }
- static void ion_handle_get(struct ion_handle *handle)
- {
-       kref_get(&handle->ref);
- }
- int ion_handle_put_nolock(struct ion_handle *handle)
- {
-       return kref_put(&handle->ref, ion_handle_destroy);
- }
- int ion_handle_put(struct ion_handle *handle)
- {
-       struct ion_client *client = handle->client;
-       int ret;
-       mutex_lock(&client->lock);
-       ret = ion_handle_put_nolock(handle);
-       mutex_unlock(&client->lock);
-       return ret;
- }
- static struct ion_handle *ion_handle_lookup(struct ion_client *client,
-                                           struct ion_buffer *buffer)
- {
-       struct rb_node *n = client->handles.rb_node;
-       while (n) {
-               struct ion_handle *entry = rb_entry(n, struct ion_handle, node);
-               if (buffer < entry->buffer)
-                       n = n->rb_left;
-               else if (buffer > entry->buffer)
-                       n = n->rb_right;
-               else
-                       return entry;
-       }
-       return ERR_PTR(-EINVAL);
- }
- struct ion_handle *ion_handle_get_by_id_nolock(struct ion_client *client,
-                                              int id)
- {
-       struct ion_handle *handle;
-       handle = idr_find(&client->idr, id);
-       if (handle)
-               ion_handle_get(handle);
-       return handle ? handle : ERR_PTR(-EINVAL);
- }
- struct ion_handle *ion_handle_get_by_id(struct ion_client *client,
-                                              int id)
- {
-       struct ion_handle *handle;
-       mutex_lock(&client->lock);
-       handle = ion_handle_get_by_id_nolock(client, id);
-       mutex_unlock(&client->lock);
-       return handle;
- }
- static bool ion_handle_validate(struct ion_client *client,
-                               struct ion_handle *handle)
- {
-       WARN_ON(!mutex_is_locked(&client->lock));
-       return idr_find(&client->idr, handle->id) == handle;
- }
- static int ion_handle_add(struct ion_client *client, struct ion_handle *handle)
- {
-       int id;
-       struct rb_node **p = &client->handles.rb_node;
-       struct rb_node *parent = NULL;
-       struct ion_handle *entry;
-       id = idr_alloc(&client->idr, handle, 1, 0, GFP_KERNEL);
-       if (id < 0)
-               return id;
-       handle->id = id;
-       while (*p) {
-               parent = *p;
-               entry = rb_entry(parent, struct ion_handle, node);
-               if (handle->buffer < entry->buffer)
-                       p = &(*p)->rb_left;
-               else if (handle->buffer > entry->buffer)
-                       p = &(*p)->rb_right;
-               else
-                       WARN(1, "%s: buffer already found.", __func__);
-       }
-       rb_link_node(&handle->node, parent, p);
-       rb_insert_color(&handle->node, &client->handles);
-       return 0;
- }
- struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
-                            size_t align, unsigned int heap_id_mask,
-                            unsigned int flags)
- {
-       struct ion_handle *handle;
-       struct ion_device *dev = client->dev;
-       struct ion_buffer *buffer = NULL;
-       struct ion_heap *heap;
-       int ret;
-       pr_debug("%s: len %zu align %zu heap_id_mask %u flags %x\n", __func__,
-                len, align, heap_id_mask, flags);
-       /*
-        * traverse the list of heaps available in this system in priority
-        * order.  If the heap type is supported by the client, and matches the
-        * request of the caller allocate from it.  Repeat until allocate has
-        * succeeded or all heaps have been tried
-        */
-       len = PAGE_ALIGN(len);
-       if (!len)
-               return ERR_PTR(-EINVAL);
-       down_read(&dev->lock);
-       plist_for_each_entry(heap, &dev->heaps, node) {
-               /* if the caller didn't specify this heap id */
-               if (!((1 << heap->id) & heap_id_mask))
-                       continue;
-               buffer = ion_buffer_create(heap, dev, len, align, flags);
-               if (!IS_ERR(buffer))
-                       break;
-       }
-       up_read(&dev->lock);
-       if (buffer == NULL)
-               return ERR_PTR(-ENODEV);
-       if (IS_ERR(buffer))
-               return ERR_CAST(buffer);
-       handle = ion_handle_create(client, buffer);
-       /*
-        * ion_buffer_create will create a buffer with a ref_cnt of 1,
-        * and ion_handle_create will take a second reference, drop one here
-        */
-       ion_buffer_put(buffer);
-       if (IS_ERR(handle))
-               return handle;
-       mutex_lock(&client->lock);
-       ret = ion_handle_add(client, handle);
-       mutex_unlock(&client->lock);
-       if (ret) {
-               ion_handle_put(handle);
-               handle = ERR_PTR(ret);
-       }
-       return handle;
- }
- EXPORT_SYMBOL(ion_alloc);
- void ion_free_nolock(struct ion_client *client,
-                    struct ion_handle *handle)
- {
-       if (!ion_handle_validate(client, handle)) {
-               WARN(1, "%s: invalid handle passed to free.\n", __func__);
-               return;
-       }
-       ion_handle_put_nolock(handle);
- }
- void ion_free(struct ion_client *client, struct ion_handle *handle)
- {
-       BUG_ON(client != handle->client);
-       mutex_lock(&client->lock);
-       ion_free_nolock(client, handle);
-       mutex_unlock(&client->lock);
- }
- EXPORT_SYMBOL(ion_free);
  static void *ion_buffer_kmap_get(struct ion_buffer *buffer)
  {
        void *vaddr;
        return vaddr;
  }
  
- static void *ion_handle_kmap_get(struct ion_handle *handle)
- {
-       struct ion_buffer *buffer = handle->buffer;
-       void *vaddr;
-       if (handle->kmap_cnt) {
-               handle->kmap_cnt++;
-               return buffer->vaddr;
-       }
-       vaddr = ion_buffer_kmap_get(buffer);
-       if (IS_ERR(vaddr))
-               return vaddr;
-       handle->kmap_cnt++;
-       return vaddr;
- }
  static void ion_buffer_kmap_put(struct ion_buffer *buffer)
  {
        buffer->kmap_cnt--;
        }
  }
  
- static void ion_handle_kmap_put(struct ion_handle *handle)
+ static struct sg_table *dup_sg_table(struct sg_table *table)
  {
-       struct ion_buffer *buffer = handle->buffer;
+       struct sg_table *new_table;
+       int ret, i;
+       struct scatterlist *sg, *new_sg;
  
-       if (!handle->kmap_cnt) {
-               WARN(1, "%s: Double unmap detected! bailing...\n", __func__);
-               return;
-       }
-       handle->kmap_cnt--;
-       if (!handle->kmap_cnt)
-               ion_buffer_kmap_put(buffer);
- }
- void *ion_map_kernel(struct ion_client *client, struct ion_handle *handle)
- {
-       struct ion_buffer *buffer;
-       void *vaddr;
-       mutex_lock(&client->lock);
-       if (!ion_handle_validate(client, handle)) {
-               pr_err("%s: invalid handle passed to map_kernel.\n",
-                      __func__);
-               mutex_unlock(&client->lock);
-               return ERR_PTR(-EINVAL);
-       }
-       buffer = handle->buffer;
-       if (!handle->buffer->heap->ops->map_kernel) {
-               pr_err("%s: map_kernel is not implemented by this heap.\n",
-                      __func__);
-               mutex_unlock(&client->lock);
-               return ERR_PTR(-ENODEV);
-       }
-       mutex_lock(&buffer->lock);
-       vaddr = ion_handle_kmap_get(handle);
-       mutex_unlock(&buffer->lock);
-       mutex_unlock(&client->lock);
-       return vaddr;
- }
- EXPORT_SYMBOL(ion_map_kernel);
- void ion_unmap_kernel(struct ion_client *client, struct ion_handle *handle)
- {
-       struct ion_buffer *buffer;
-       mutex_lock(&client->lock);
-       buffer = handle->buffer;
-       mutex_lock(&buffer->lock);
-       ion_handle_kmap_put(handle);
-       mutex_unlock(&buffer->lock);
-       mutex_unlock(&client->lock);
- }
- EXPORT_SYMBOL(ion_unmap_kernel);
- static struct mutex debugfs_mutex;
- static struct rb_root *ion_root_client;
- static int is_client_alive(struct ion_client *client)
- {
-       struct rb_node *node;
-       struct ion_client *tmp;
-       struct ion_device *dev;
-       node = ion_root_client->rb_node;
-       dev = container_of(ion_root_client, struct ion_device, clients);
-       down_read(&dev->lock);
-       while (node) {
-               tmp = rb_entry(node, struct ion_client, node);
-               if (client < tmp) {
-                       node = node->rb_left;
-               } else if (client > tmp) {
-                       node = node->rb_right;
-               } else {
-                       up_read(&dev->lock);
-                       return 1;
-               }
-       }
-       up_read(&dev->lock);
-       return 0;
- }
+       new_table = kzalloc(sizeof(*new_table), GFP_KERNEL);
+       if (!new_table)
+               return ERR_PTR(-ENOMEM);
  
- static int ion_debug_client_show(struct seq_file *s, void *unused)
- {
-       struct ion_client *client = s->private;
-       struct rb_node *n;
-       size_t sizes[ION_NUM_HEAP_IDS] = {0};
-       const char *names[ION_NUM_HEAP_IDS] = {NULL};
-       int i;
-       mutex_lock(&debugfs_mutex);
-       if (!is_client_alive(client)) {
-               seq_printf(s, "ion_client 0x%p dead, can't dump its buffers\n",
-                          client);
-               mutex_unlock(&debugfs_mutex);
-               return 0;
+       ret = sg_alloc_table(new_table, table->nents, GFP_KERNEL);
+       if (ret) {
+               kfree(new_table);
+               return ERR_PTR(-ENOMEM);
        }
  
-       mutex_lock(&client->lock);
-       for (n = rb_first(&client->handles); n; n = rb_next(n)) {
-               struct ion_handle *handle = rb_entry(n, struct ion_handle,
-                                                    node);
-               unsigned int id = handle->buffer->heap->id;
-               if (!names[id])
-                       names[id] = handle->buffer->heap->name;
-               sizes[id] += handle->buffer->size;
+       new_sg = new_table->sgl;
+       for_each_sg(table->sgl, sg, table->nents, i) {
+               memcpy(new_sg, sg, sizeof(*sg));
+               sg->dma_address = 0;
+               new_sg = sg_next(new_sg);
        }
-       mutex_unlock(&client->lock);
-       mutex_unlock(&debugfs_mutex);
  
-       seq_printf(s, "%16.16s: %16.16s\n", "heap_name", "size_in_bytes");
-       for (i = 0; i < ION_NUM_HEAP_IDS; i++) {
-               if (!names[i])
-                       continue;
-               seq_printf(s, "%16.16s: %16zu\n", names[i], sizes[i]);
-       }
-       return 0;
+       return new_table;
  }
  
- static int ion_debug_client_open(struct inode *inode, struct file *file)
+ static void free_duped_table(struct sg_table *table)
  {
-       return single_open(file, ion_debug_client_show, inode->i_private);
+       sg_free_table(table);
+       kfree(table);
  }
  
- static const struct file_operations debug_client_fops = {
-       .open = ion_debug_client_open,
-       .read = seq_read,
-       .llseek = seq_lseek,
-       .release = single_release,
+ struct ion_dma_buf_attachment {
+       struct device *dev;
+       struct sg_table *table;
+       struct list_head list;
  };
  
- static int ion_get_client_serial(const struct rb_root *root,
-                                const unsigned char *name)
- {
-       int serial = -1;
-       struct rb_node *node;
-       for (node = rb_first(root); node; node = rb_next(node)) {
-               struct ion_client *client = rb_entry(node, struct ion_client,
-                                                    node);
-               if (strcmp(client->name, name))
-                       continue;
-               serial = max(serial, client->display_serial);
-       }
-       return serial + 1;
- }
- struct ion_client *ion_client_create(struct ion_device *dev,
-                                    const char *name)
+ static int ion_dma_buf_attach(struct dma_buf *dmabuf, struct device *dev,
+                               struct dma_buf_attachment *attachment)
  {
-       struct ion_client *client;
-       struct task_struct *task;
-       struct rb_node **p;
-       struct rb_node *parent = NULL;
-       struct ion_client *entry;
-       pid_t pid;
-       if (!name) {
-               pr_err("%s: Name cannot be null\n", __func__);
-               return ERR_PTR(-EINVAL);
-       }
+       struct ion_dma_buf_attachment *a;
+       struct sg_table *table;
+       struct ion_buffer *buffer = dmabuf->priv;
  
-       get_task_struct(current->group_leader);
-       task_lock(current->group_leader);
-       pid = task_pid_nr(current->group_leader);
-       /*
-        * don't bother to store task struct for kernel threads,
-        * they can't be killed anyway
-        */
-       if (current->group_leader->flags & PF_KTHREAD) {
-               put_task_struct(current->group_leader);
-               task = NULL;
-       } else {
-               task = current->group_leader;
-       }
-       task_unlock(current->group_leader);
-       client = kzalloc(sizeof(*client), GFP_KERNEL);
-       if (!client)
-               goto err_put_task_struct;
-       client->dev = dev;
-       client->handles = RB_ROOT;
-       idr_init(&client->idr);
-       mutex_init(&client->lock);
-       client->task = task;
-       client->pid = pid;
-       client->name = kstrdup(name, GFP_KERNEL);
-       if (!client->name)
-               goto err_free_client;
+       a = kzalloc(sizeof(*a), GFP_KERNEL);
+       if (!a)
+               return -ENOMEM;
  
-       down_write(&dev->lock);
-       client->display_serial = ion_get_client_serial(&dev->clients, name);
-       client->display_name = kasprintf(
-               GFP_KERNEL, "%s-%d", name, client->display_serial);
-       if (!client->display_name) {
-               up_write(&dev->lock);
-               goto err_free_client_name;
+       table = dup_sg_table(buffer->sg_table);
+       if (IS_ERR(table)) {
+               kfree(a);
+               return -ENOMEM;
        }
-       p = &dev->clients.rb_node;
-       while (*p) {
-               parent = *p;
-               entry = rb_entry(parent, struct ion_client, node);
  
-               if (client < entry)
-                       p = &(*p)->rb_left;
-               else if (client > entry)
-                       p = &(*p)->rb_right;
-       }
-       rb_link_node(&client->node, parent, p);
-       rb_insert_color(&client->node, &dev->clients);
-       client->debug_root = debugfs_create_file(client->display_name, 0664,
-                                                dev->clients_debug_root,
-                                                client, &debug_client_fops);
-       if (!client->debug_root) {
-               char buf[256], *path;
-               path = dentry_path(dev->clients_debug_root, buf, 256);
-               pr_err("Failed to create client debugfs at %s/%s\n",
-                      path, client->display_name);
-       }
+       a->table = table;
+       a->dev = dev;
+       INIT_LIST_HEAD(&a->list);
  
-       up_write(&dev->lock);
+       attachment->priv = a;
  
-       return client;
+       mutex_lock(&buffer->lock);
+       list_add(&a->list, &buffer->attachments);
+       mutex_unlock(&buffer->lock);
  
- err_free_client_name:
-       kfree(client->name);
- err_free_client:
-       kfree(client);
- err_put_task_struct:
-       if (task)
-               put_task_struct(current->group_leader);
-       return ERR_PTR(-ENOMEM);
+       return 0;
  }
- EXPORT_SYMBOL(ion_client_create);
  
- void ion_client_destroy(struct ion_client *client)
+ static void ion_dma_buf_detatch(struct dma_buf *dmabuf,
+                               struct dma_buf_attachment *attachment)
  {
-       struct ion_device *dev = client->dev;
-       struct rb_node *n;
-       pr_debug("%s: %d\n", __func__, __LINE__);
-       mutex_lock(&debugfs_mutex);
-       while ((n = rb_first(&client->handles))) {
-               struct ion_handle *handle = rb_entry(n, struct ion_handle,
-                                                    node);
-               ion_handle_destroy(&handle->ref);
-       }
-       idr_destroy(&client->idr);
+       struct ion_dma_buf_attachment *a = attachment->priv;
+       struct ion_buffer *buffer = dmabuf->priv;
  
-       down_write(&dev->lock);
-       if (client->task)
-               put_task_struct(client->task);
-       rb_erase(&client->node, &dev->clients);
-       debugfs_remove_recursive(client->debug_root);
-       up_write(&dev->lock);
+       free_duped_table(a->table);
+       mutex_lock(&buffer->lock);
+       list_del(&a->list);
+       mutex_unlock(&buffer->lock);
  
-       kfree(client->display_name);
-       kfree(client->name);
-       kfree(client);
-       mutex_unlock(&debugfs_mutex);
+       kfree(a);
  }
- EXPORT_SYMBOL(ion_client_destroy);
  
- static void ion_buffer_sync_for_device(struct ion_buffer *buffer,
-                                      struct device *dev,
-                                      enum dma_data_direction direction);
  
  static struct sg_table *ion_map_dma_buf(struct dma_buf_attachment *attachment,
                                        enum dma_data_direction direction)
  {
-       struct dma_buf *dmabuf = attachment->dmabuf;
-       struct ion_buffer *buffer = dmabuf->priv;
-       ion_buffer_sync_for_device(buffer, attachment->dev, direction);
-       return buffer->sg_table;
- }
- static void ion_unmap_dma_buf(struct dma_buf_attachment *attachment,
-                             struct sg_table *table,
-                             enum dma_data_direction direction)
- {
- }
- void ion_pages_sync_for_device(struct device *dev, struct page *page,
-                              size_t size, enum dma_data_direction dir)
- {
-       struct scatterlist sg;
-       sg_init_table(&sg, 1);
-       sg_set_page(&sg, page, size, 0);
-       /*
-        * This is not correct - sg_dma_address needs a dma_addr_t that is valid
-        * for the targeted device, but this works on the currently targeted
-        * hardware.
-        */
-       sg_dma_address(&sg) = page_to_phys(page);
-       dma_sync_sg_for_device(dev, &sg, 1, dir);
- }
- struct ion_vma_list {
-       struct list_head list;
-       struct vm_area_struct *vma;
- };
- static void ion_buffer_sync_for_device(struct ion_buffer *buffer,
-                                      struct device *dev,
-                                      enum dma_data_direction dir)
- {
-       struct ion_vma_list *vma_list;
-       int pages = PAGE_ALIGN(buffer->size) / PAGE_SIZE;
-       int i;
-       pr_debug("%s: syncing for device %s\n", __func__,
-                dev ? dev_name(dev) : "null");
-       if (!ion_buffer_fault_user_mappings(buffer))
-               return;
-       mutex_lock(&buffer->lock);
-       for (i = 0; i < pages; i++) {
-               struct page *page = buffer->pages[i];
-               if (ion_buffer_page_is_dirty(page))
-                       ion_pages_sync_for_device(dev, ion_buffer_page(page),
-                                                 PAGE_SIZE, dir);
-               ion_buffer_page_clean(buffer->pages + i);
-       }
-       list_for_each_entry(vma_list, &buffer->vmas, list) {
-               struct vm_area_struct *vma = vma_list->vma;
-               zap_page_range(vma, vma->vm_start, vma->vm_end - vma->vm_start);
-       }
-       mutex_unlock(&buffer->lock);
- }
- static int ion_vm_fault(struct vm_fault *vmf)
- {
-       struct ion_buffer *buffer = vmf->vma->vm_private_data;
-       unsigned long pfn;
+       struct ion_dma_buf_attachment *a = attachment->priv;
+       struct sg_table *table;
        int ret;
  
-       mutex_lock(&buffer->lock);
-       ion_buffer_page_dirty(buffer->pages + vmf->pgoff);
-       BUG_ON(!buffer->pages || !buffer->pages[vmf->pgoff]);
-       pfn = page_to_pfn(ion_buffer_page(buffer->pages[vmf->pgoff]));
-       ret = vm_insert_pfn(vmf->vma, vmf->address, pfn);
-       mutex_unlock(&buffer->lock);
-       if (ret)
-               return VM_FAULT_ERROR;
+       table = a->table;
  
-       return VM_FAULT_NOPAGE;
- }
- static void ion_vm_open(struct vm_area_struct *vma)
- {
-       struct ion_buffer *buffer = vma->vm_private_data;
-       struct ion_vma_list *vma_list;
+       if (!dma_map_sg(attachment->dev, table->sgl, table->nents,
+                       direction)){
+               ret = -ENOMEM;
+               goto err;
+       }
+       return table;
  
-       vma_list = kmalloc(sizeof(*vma_list), GFP_KERNEL);
-       if (!vma_list)
-               return;
-       vma_list->vma = vma;
-       mutex_lock(&buffer->lock);
-       list_add(&vma_list->list, &buffer->vmas);
-       mutex_unlock(&buffer->lock);
-       pr_debug("%s: adding %p\n", __func__, vma);
+ err:
+       free_duped_table(table);
+       return ERR_PTR(ret);
  }
  
- static void ion_vm_close(struct vm_area_struct *vma)
+ static void ion_unmap_dma_buf(struct dma_buf_attachment *attachment,
+                             struct sg_table *table,
+                             enum dma_data_direction direction)
  {
-       struct ion_buffer *buffer = vma->vm_private_data;
-       struct ion_vma_list *vma_list, *tmp;
-       pr_debug("%s\n", __func__);
-       mutex_lock(&buffer->lock);
-       list_for_each_entry_safe(vma_list, tmp, &buffer->vmas, list) {
-               if (vma_list->vma != vma)
-                       continue;
-               list_del(&vma_list->list);
-               kfree(vma_list);
-               pr_debug("%s: deleting %p\n", __func__, vma);
-               break;
-       }
-       mutex_unlock(&buffer->lock);
+       dma_unmap_sg(attachment->dev, table->sgl, table->nents, direction);
  }
  
- static const struct vm_operations_struct ion_vma_ops = {
-       .open = ion_vm_open,
-       .close = ion_vm_close,
-       .fault = ion_vm_fault,
- };
  static int ion_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
  {
        struct ion_buffer *buffer = dmabuf->priv;
                return -EINVAL;
        }
  
-       if (ion_buffer_fault_user_mappings(buffer)) {
-               vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND |
-                                                       VM_DONTDUMP;
-               vma->vm_private_data = buffer;
-               vma->vm_ops = &ion_vma_ops;
-               ion_vm_open(vma);
-               return 0;
-       }
        if (!(buffer->flags & ION_FLAG_CACHED))
                vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  
@@@ -968,7 -323,7 +323,7 @@@ static void ion_dma_buf_release(struct 
  {
        struct ion_buffer *buffer = dmabuf->priv;
  
-       ion_buffer_put(buffer);
+       _ion_buffer_destroy(buffer);
  }
  
  static void *ion_dma_buf_kmap(struct dma_buf *dmabuf, unsigned long offset)
@@@ -988,26 -343,45 +343,45 @@@ static int ion_dma_buf_begin_cpu_access
  {
        struct ion_buffer *buffer = dmabuf->priv;
        void *vaddr;
+       struct ion_dma_buf_attachment *a;
  
-       if (!buffer->heap->ops->map_kernel) {
-               pr_err("%s: map kernel is not implemented by this heap.\n",
-                      __func__);
-               return -ENODEV;
+       /*
+        * TODO: Move this elsewhere because we don't always need a vaddr
+        */
+       if (buffer->heap->ops->map_kernel) {
+               mutex_lock(&buffer->lock);
+               vaddr = ion_buffer_kmap_get(buffer);
+               mutex_unlock(&buffer->lock);
        }
  
        mutex_lock(&buffer->lock);
-       vaddr = ion_buffer_kmap_get(buffer);
+       list_for_each_entry(a, &buffer->attachments, list) {
+               dma_sync_sg_for_cpu(a->dev, a->table->sgl, a->table->nents,
+                                       DMA_BIDIRECTIONAL);
+       }
        mutex_unlock(&buffer->lock);
-       return PTR_ERR_OR_ZERO(vaddr);
+       return 0;
  }
  
  static int ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf,
                                      enum dma_data_direction direction)
  {
        struct ion_buffer *buffer = dmabuf->priv;
+       struct ion_dma_buf_attachment *a;
+       if (buffer->heap->ops->map_kernel) {
+               mutex_lock(&buffer->lock);
+               ion_buffer_kmap_put(buffer);
+               mutex_unlock(&buffer->lock);
+       }
  
        mutex_lock(&buffer->lock);
-       ion_buffer_kmap_put(buffer);
+       list_for_each_entry(a, &buffer->attachments, list) {
+               dma_sync_sg_for_device(a->dev, a->table->sgl, a->table->nents,
+                                       DMA_BIDIRECTIONAL);
+       }
        mutex_unlock(&buffer->lock);
  
        return 0;
@@@ -1018,32 -392,54 +392,54 @@@ static const struct dma_buf_ops dma_buf
        .unmap_dma_buf = ion_unmap_dma_buf,
        .mmap = ion_mmap,
        .release = ion_dma_buf_release,
+       .attach = ion_dma_buf_attach,
+       .detach = ion_dma_buf_detatch,
        .begin_cpu_access = ion_dma_buf_begin_cpu_access,
        .end_cpu_access = ion_dma_buf_end_cpu_access,
 -      .kmap_atomic = ion_dma_buf_kmap,
 -      .kunmap_atomic = ion_dma_buf_kunmap,
 -      .kmap = ion_dma_buf_kmap,
 -      .kunmap = ion_dma_buf_kunmap,
 +      .map_atomic = ion_dma_buf_kmap,
 +      .unmap_atomic = ion_dma_buf_kunmap,
 +      .map = ion_dma_buf_kmap,
 +      .unmap = ion_dma_buf_kunmap,
  };
  
- struct dma_buf *ion_share_dma_buf(struct ion_client *client,
-                                 struct ion_handle *handle)
+ int ion_alloc(size_t len, unsigned int heap_id_mask, unsigned int flags)
  {
+       struct ion_device *dev = internal_dev;
+       struct ion_buffer *buffer = NULL;
+       struct ion_heap *heap;
        DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
-       struct ion_buffer *buffer;
+       int fd;
        struct dma_buf *dmabuf;
-       bool valid_handle;
  
-       mutex_lock(&client->lock);
-       valid_handle = ion_handle_validate(client, handle);
-       if (!valid_handle) {
-               WARN(1, "%s: invalid handle passed to share.\n", __func__);
-               mutex_unlock(&client->lock);
-               return ERR_PTR(-EINVAL);
+       pr_debug("%s: len %zu heap_id_mask %u flags %x\n", __func__,
+                len, heap_id_mask, flags);
+       /*
+        * traverse the list of heaps available in this system in priority
+        * order.  If the heap type is supported by the client, and matches the
+        * request of the caller allocate from it.  Repeat until allocate has
+        * succeeded or all heaps have been tried
+        */
+       len = PAGE_ALIGN(len);
+       if (!len)
+               return -EINVAL;
+       down_read(&dev->lock);
+       plist_for_each_entry(heap, &dev->heaps, node) {
+               /* if the caller didn't specify this heap id */
+               if (!((1 << heap->id) & heap_id_mask))
+                       continue;
+               buffer = ion_buffer_create(heap, dev, len, flags);
+               if (!IS_ERR(buffer))
+                       break;
        }
-       buffer = handle->buffer;
-       ion_buffer_get(buffer);
-       mutex_unlock(&client->lock);
+       up_read(&dev->lock);
+       if (buffer == NULL)
+               return -ENODEV;
+       if (IS_ERR(buffer))
+               return PTR_ERR(buffer);
  
        exp_info.ops = &dma_buf_ops;
        exp_info.size = buffer->size;
  
        dmabuf = dma_buf_export(&exp_info);
        if (IS_ERR(dmabuf)) {
-               ion_buffer_put(buffer);
-               return dmabuf;
-       }
-       return dmabuf;
- }
- EXPORT_SYMBOL(ion_share_dma_buf);
- int ion_share_dma_buf_fd(struct ion_client *client, struct ion_handle *handle)
- {
-       struct dma_buf *dmabuf;
-       int fd;
-       dmabuf = ion_share_dma_buf(client, handle);
-       if (IS_ERR(dmabuf))
+               _ion_buffer_destroy(buffer);
                return PTR_ERR(dmabuf);
+       }
  
        fd = dma_buf_fd(dmabuf, O_CLOEXEC);
        if (fd < 0)
  
        return fd;
  }
- EXPORT_SYMBOL(ion_share_dma_buf_fd);
- struct ion_handle *ion_import_dma_buf(struct ion_client *client,
-                                     struct dma_buf *dmabuf)
- {
-       struct ion_buffer *buffer;
-       struct ion_handle *handle;
-       int ret;
-       /* if this memory came from ion */
-       if (dmabuf->ops != &dma_buf_ops) {
-               pr_err("%s: can not import dmabuf from another exporter\n",
-                      __func__);
-               return ERR_PTR(-EINVAL);
-       }
-       buffer = dmabuf->priv;
-       mutex_lock(&client->lock);
-       /* if a handle exists for this buffer just take a reference to it */
-       handle = ion_handle_lookup(client, buffer);
-       if (!IS_ERR(handle)) {
-               ion_handle_get(handle);
-               mutex_unlock(&client->lock);
-               goto end;
-       }
-       handle = ion_handle_create(client, buffer);
-       if (IS_ERR(handle)) {
-               mutex_unlock(&client->lock);
-               goto end;
-       }
-       ret = ion_handle_add(client, handle);
-       mutex_unlock(&client->lock);
-       if (ret) {
-               ion_handle_put(handle);
-               handle = ERR_PTR(ret);
-       }
- end:
-       return handle;
- }
- EXPORT_SYMBOL(ion_import_dma_buf);
- struct ion_handle *ion_import_dma_buf_fd(struct ion_client *client, int fd)
- {
-       struct dma_buf *dmabuf;
-       struct ion_handle *handle;
-       dmabuf = dma_buf_get(fd);
-       if (IS_ERR(dmabuf))
-               return ERR_CAST(dmabuf);
-       handle = ion_import_dma_buf(client, dmabuf);
-       dma_buf_put(dmabuf);
-       return handle;
- }
- EXPORT_SYMBOL(ion_import_dma_buf_fd);
- int ion_sync_for_device(struct ion_client *client, int fd)
- {
-       struct dma_buf *dmabuf;
-       struct ion_buffer *buffer;
-       dmabuf = dma_buf_get(fd);
-       if (IS_ERR(dmabuf))
-               return PTR_ERR(dmabuf);
-       /* if this memory came from ion */
-       if (dmabuf->ops != &dma_buf_ops) {
-               pr_err("%s: can not sync dmabuf from another exporter\n",
-                      __func__);
-               dma_buf_put(dmabuf);
-               return -EINVAL;
-       }
-       buffer = dmabuf->priv;
-       dma_sync_sg_for_device(NULL, buffer->sg_table->sgl,
-                              buffer->sg_table->nents, DMA_BIDIRECTIONAL);
-       dma_buf_put(dmabuf);
-       return 0;
- }
  
- int ion_query_heaps(struct ion_client *client, struct ion_heap_query *query)
+ int ion_query_heaps(struct ion_heap_query *query)
  {
-       struct ion_device *dev = client->dev;
+       struct ion_device *dev = internal_dev;
        struct ion_heap_data __user *buffer = u64_to_user_ptr(query->heaps);
        int ret = -EINVAL, cnt = 0, max_cnt;
        struct ion_heap *heap;
        }
  
        query->cnt = cnt;
+       ret = 0;
  out:
        up_read(&dev->lock);
        return ret;
  }
  
- static int ion_release(struct inode *inode, struct file *file)
- {
-       struct ion_client *client = file->private_data;
-       pr_debug("%s: %d\n", __func__, __LINE__);
-       ion_client_destroy(client);
-       return 0;
- }
- static int ion_open(struct inode *inode, struct file *file)
- {
-       struct miscdevice *miscdev = file->private_data;
-       struct ion_device *dev = container_of(miscdev, struct ion_device, dev);
-       struct ion_client *client;
-       char debug_name[64];
-       pr_debug("%s: %d\n", __func__, __LINE__);
-       snprintf(debug_name, 64, "%u", task_pid_nr(current->group_leader));
-       client = ion_client_create(dev, debug_name);
-       if (IS_ERR(client))
-               return PTR_ERR(client);
-       file->private_data = client;
-       return 0;
- }
  static const struct file_operations ion_fops = {
        .owner          = THIS_MODULE,
-       .open           = ion_open,
-       .release        = ion_release,
        .unlocked_ioctl = ion_ioctl,
-       .compat_ioctl   = compat_ion_ioctl,
- };
- static size_t ion_debug_heap_total(struct ion_client *client,
-                                  unsigned int id)
- {
-       size_t size = 0;
-       struct rb_node *n;
-       mutex_lock(&client->lock);
-       for (n = rb_first(&client->handles); n; n = rb_next(n)) {
-               struct ion_handle *handle = rb_entry(n,
-                                                    struct ion_handle,
-                                                    node);
-               if (handle->buffer->heap->id == id)
-                       size += handle->buffer->size;
-       }
-       mutex_unlock(&client->lock);
-       return size;
- }
- static int ion_debug_heap_show(struct seq_file *s, void *unused)
- {
-       struct ion_heap *heap = s->private;
-       struct ion_device *dev = heap->dev;
-       struct rb_node *n;
-       size_t total_size = 0;
-       size_t total_orphaned_size = 0;
-       seq_printf(s, "%16s %16s %16s\n", "client", "pid", "size");
-       seq_puts(s, "----------------------------------------------------\n");
-       mutex_lock(&debugfs_mutex);
-       for (n = rb_first(&dev->clients); n; n = rb_next(n)) {
-               struct ion_client *client = rb_entry(n, struct ion_client,
-                                                    node);
-               size_t size = ion_debug_heap_total(client, heap->id);
-               if (!size)
-                       continue;
-               if (client->task) {
-                       char task_comm[TASK_COMM_LEN];
-                       get_task_comm(task_comm, client->task);
-                       seq_printf(s, "%16s %16u %16zu\n", task_comm,
-                                  client->pid, size);
-               } else {
-                       seq_printf(s, "%16s %16u %16zu\n", client->name,
-                                  client->pid, size);
-               }
-       }
-       mutex_unlock(&debugfs_mutex);
-       seq_puts(s, "----------------------------------------------------\n");
-       seq_puts(s, "orphaned allocations (info is from last known client):\n");
-       mutex_lock(&dev->buffer_lock);
-       for (n = rb_first(&dev->buffers); n; n = rb_next(n)) {
-               struct ion_buffer *buffer = rb_entry(n, struct ion_buffer,
-                                                    node);
-               if (buffer->heap->id != heap->id)
-                       continue;
-               total_size += buffer->size;
-               if (!buffer->handle_count) {
-                       seq_printf(s, "%16s %16u %16zu %d %d\n",
-                                  buffer->task_comm, buffer->pid,
-                                  buffer->size, buffer->kmap_cnt,
-                                  kref_read(&buffer->ref));
-                       total_orphaned_size += buffer->size;
-               }
-       }
-       mutex_unlock(&dev->buffer_lock);
-       seq_puts(s, "----------------------------------------------------\n");
-       seq_printf(s, "%16s %16zu\n", "total orphaned",
-                  total_orphaned_size);
-       seq_printf(s, "%16s %16zu\n", "total ", total_size);
-       if (heap->flags & ION_HEAP_FLAG_DEFER_FREE)
-               seq_printf(s, "%16s %16zu\n", "deferred free",
-                          heap->free_list_size);
-       seq_puts(s, "----------------------------------------------------\n");
-       if (heap->debug_show)
-               heap->debug_show(heap, s, unused);
-       return 0;
- }
- static int ion_debug_heap_open(struct inode *inode, struct file *file)
- {
-       return single_open(file, ion_debug_heap_show, inode->i_private);
- }
- static const struct file_operations debug_heap_fops = {
-       .open = ion_debug_heap_open,
-       .read = seq_read,
-       .llseek = seq_lseek,
-       .release = single_release,
+ #ifdef CONFIG_COMPAT
+       .compat_ioctl   = ion_ioctl,
+ #endif
  };
  
  static int debug_shrink_set(void *data, u64 val)
@@@ -1367,9 -547,10 +547,10 @@@ static int debug_shrink_get(void *data
  DEFINE_SIMPLE_ATTRIBUTE(debug_shrink_fops, debug_shrink_get,
                        debug_shrink_set, "%llu\n");
  
- void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap)
+ void ion_device_add_heap(struct ion_heap *heap)
  {
        struct dentry *debug_file;
+       struct ion_device *dev = internal_dev;
  
        if (!heap->ops->allocate || !heap->ops->free)
                pr_err("%s: can not add heap with invalid ops struct.\n",
  
        heap->dev = dev;
        down_write(&dev->lock);
+       heap->id = heap_id++;
        /*
         * use negative heap->id to reverse the priority -- when traversing
         * the list later attempt higher id numbers first
         */
        plist_node_init(&heap->node, -heap->id);
        plist_add(&heap->node, &dev->heaps);
-       debug_file = debugfs_create_file(heap->name, 0664,
-                                        dev->heaps_debug_root, heap,
-                                        &debug_heap_fops);
-       if (!debug_file) {
-               char buf[256], *path;
-               path = dentry_path(dev->heaps_debug_root, buf, 256);
-               pr_err("Failed to create heap debugfs at %s/%s\n",
-                      path, heap->name);
-       }
  
        if (heap->shrinker.count_objects && heap->shrinker.scan_objects) {
                char debug_name[64];
  
                snprintf(debug_name, 64, "%s_shrink", heap->name);
                debug_file = debugfs_create_file(
-                       debug_name, 0644, dev->heaps_debug_root, heap,
+                       debug_name, 0644, dev->debug_root, heap,
                        &debug_shrink_fops);
                if (!debug_file) {
                        char buf[256], *path;
  
-                       path = dentry_path(dev->heaps_debug_root, buf, 256);
+                       path = dentry_path(dev->debug_root, buf, 256);
                        pr_err("Failed to create heap shrinker debugfs at %s/%s\n",
                               path, debug_name);
                }
  }
  EXPORT_SYMBOL(ion_device_add_heap);
  
- struct ion_device *ion_device_create(long (*custom_ioctl)
-                                    (struct ion_client *client,
-                                     unsigned int cmd,
-                                     unsigned long arg))
+ int ion_device_create(void)
  {
        struct ion_device *idev;
        int ret;
  
        idev = kzalloc(sizeof(*idev), GFP_KERNEL);
        if (!idev)
-               return ERR_PTR(-ENOMEM);
+               return -ENOMEM;
  
        idev->dev.minor = MISC_DYNAMIC_MINOR;
        idev->dev.name = "ion";
        if (ret) {
                pr_err("ion: failed to register misc device.\n");
                kfree(idev);
-               return ERR_PTR(ret);
+               return ret;
        }
  
        idev->debug_root = debugfs_create_dir("ion", NULL);
                pr_err("ion: failed to create debugfs root directory.\n");
                goto debugfs_done;
        }
-       idev->heaps_debug_root = debugfs_create_dir("heaps", idev->debug_root);
-       if (!idev->heaps_debug_root) {
-               pr_err("ion: failed to create debugfs heaps directory.\n");
-               goto debugfs_done;
-       }
-       idev->clients_debug_root = debugfs_create_dir("clients",
-                                               idev->debug_root);
-       if (!idev->clients_debug_root)
-               pr_err("ion: failed to create debugfs clients directory.\n");
  
  debugfs_done:
-       idev->custom_ioctl = custom_ioctl;
        idev->buffers = RB_ROOT;
        mutex_init(&idev->buffer_lock);
        init_rwsem(&idev->lock);
        plist_head_init(&idev->heaps);
-       idev->clients = RB_ROOT;
-       ion_root_client = &idev->clients;
-       mutex_init(&debugfs_mutex);
-       return idev;
- }
- EXPORT_SYMBOL(ion_device_create);
- void ion_device_destroy(struct ion_device *dev)
- {
-       misc_deregister(&dev->dev);
-       debugfs_remove_recursive(dev->debug_root);
-       /* XXX need to free the heaps and clients ? */
-       kfree(dev);
+       internal_dev = idev;
+       return 0;
  }
EXPORT_SYMBOL(ion_device_destroy);
subsys_initcall(ion_device_create);
index d483c44aafe5d3cd16b62978877e216b9712ddee,7b8004071125711a70f9ba48734105f666203125..11b5a8d36415362f7d41c8fe00043f08baa6d5bc
@@@ -863,6 -863,15 +863,6 @@@ void ll_lli_init(struct ll_inode_info *
        mutex_init(&lli->lli_layout_mutex);
  }
  
 -static inline int ll_bdi_register(struct backing_dev_info *bdi)
 -{
 -      static atomic_t ll_bdi_num = ATOMIC_INIT(0);
 -
 -      bdi->name = "lustre";
 -      return bdi_register(bdi, NULL, "lustre-%d",
 -                          atomic_inc_return(&ll_bdi_num));
 -}
 -
  int ll_fill_super(struct super_block *sb, struct vfsmount *mnt)
  {
        struct lustre_profile *lprof = NULL;
        char  *profilenm = get_profile_name(sb);
        struct config_llog_instance *cfg;
        int    err;
 +      static atomic_t ll_bdi_num = ATOMIC_INIT(0);
  
        CDEBUG(D_VFSTRACE, "VFS Op: sb %p\n", sb);
  
        if (err)
                goto out_free;
  
 -      err = bdi_init(&lsi->lsi_bdi);
 -      if (err)
 -              goto out_free;
 -      lsi->lsi_flags |= LSI_BDI_INITIALIZED;
 -      lsi->lsi_bdi.capabilities = 0;
 -      err = ll_bdi_register(&lsi->lsi_bdi);
 +      err = super_setup_bdi_name(sb, "lustre-%d",
 +                                 atomic_inc_return(&ll_bdi_num));
        if (err)
                goto out_free;
  
 -      sb->s_bdi = &lsi->lsi_bdi;
        /* kernel >= 2.6.38 store dentry operations in sb->s_d_op. */
        sb->s_d_op = &ll_d_ops;
  
@@@ -1020,6 -1033,11 +1020,6 @@@ void ll_put_super(struct super_block *s
        if (profilenm)
                class_del_profile(profilenm);
  
 -      if (lsi->lsi_flags & LSI_BDI_INITIALIZED) {
 -              bdi_destroy(&lsi->lsi_bdi);
 -              lsi->lsi_flags &= ~LSI_BDI_INITIALIZED;
 -      }
 -
        ll_free_sbi(sb);
        lsi->lsi_llsbi = NULL;
  
@@@ -1486,8 -1504,6 +1486,6 @@@ int ll_setattr_raw(struct dentry *dentr
                goto out;
        }
  
-       op_data->op_attr = *attr;
        if (!hsm_import && attr->ia_valid & ATTR_SIZE) {
                /*
                 * If we are changing file size, file content is
                 */
                attr->ia_valid |= MDS_OPEN_OWNEROVERRIDE;
                op_data->op_bias |= MDS_DATA_MODIFIED;
+               clear_bit(LLIF_DATA_MODIFIED, &lli->lli_flags);
        }
  
+       op_data->op_attr = *attr;
        rc = ll_md_setattr(dentry, op_data);
        if (rc)
                goto out;
                int rc2;
  
                rc2 = ll_hsm_state_set(inode, &hss);
+               /*
+                * truncate and write can happen at the same time, so that
+                * the file can be set modified even though the file is not
+                * restored from released state, and ll_hsm_state_set() is
+                * not applicable for the file, and rc2 < 0 is normal in this
+                * case.
+                */
                if (rc2 < 0)
-                       CERROR(DFID "HSM set dirty failed: rc2 = %d\n",
+                       CDEBUG(D_INFO, DFID "HSM set dirty failed: rc2 = %d\n",
                               PFID(ll_inode2fid(inode)), rc2);
        }
  
@@@ -2486,7 -2512,7 +2494,7 @@@ no_kbuf
  void ll_compute_rootsquash_state(struct ll_sb_info *sbi)
  {
        struct root_squash_info *squash = &sbi->ll_squash;
-       lnet_process_id_t id;
+       struct lnet_process_id id;
        bool matched;
        int i;
  
index 8ed8202da57a6d889857a26b8508586a1bd099fb,5a26eb211c7a80da209b97e9412407ba618e5c21..dbda4d9a08e798ab3c15ac3df53be8b988d5aa02
@@@ -19,6 -19,6 +19,8 @@@ menuconfig STAGING_MEDI
  if STAGING_MEDIA && MEDIA_SUPPORT
  
  # Please keep them in alphabetic order
++source "drivers/staging/media/atomisp/Kconfig"
++
  source "drivers/staging/media/bcm2048/Kconfig"
  
  source "drivers/staging/media/cxd2099/Kconfig"
@@@ -27,9 -27,12 +29,7 @@@ source "drivers/staging/media/davinci_v
  
  source "drivers/staging/media/omap4iss/Kconfig"
  
- source "drivers/staging/media/platform/bcm2835/Kconfig"
 -source "drivers/staging/media/s5p-cec/Kconfig"
--
  # Keep LIRC at the end, as it has sub-menus
  source "drivers/staging/media/lirc/Kconfig"
  
 -source "drivers/staging/media/st-cec/Kconfig"
 -
 -source "drivers/staging/media/atomisp/Kconfig"
  endif
index 3a6adeabede1f77d8bfa47e03be4858666b8e415,ab60a89c6593a29b7da1df4c8a01d2f2b4139c3a..c04600c8126402844f622bca4ebd4f00cf3862d5
@@@ -1,6 -1,8 +1,6 @@@
  obj-$(CONFIG_I2C_BCM2048)     += bcm2048/
 -obj-$(CONFIG_VIDEO_SAMSUNG_S5P_CEC) += s5p-cec/
  obj-$(CONFIG_DVB_CXD2099)     += cxd2099/
  obj-$(CONFIG_LIRC_STAGING)    += lirc/
- obj-$(CONFIG_VIDEO_BCM2835)   += platform/bcm2835/
  obj-$(CONFIG_VIDEO_DM365_VPFE)        += davinci_vpfe/
  obj-$(CONFIG_VIDEO_OMAP4)     += omap4iss/
 -obj-$(CONFIG_VIDEO_STI_HDMI_CEC) += st-cec/
+ obj-$(CONFIG_INTEL_ATOMISP)     += atomisp/
index 2bfea9b48366f08c00e934a4f3bda918fb01b9d0,477c0ed305d36600b3035a63f7dfc57b268e9364..a95b5910d9fc8aca4b0cadf4f5f14ca9577707c2
@@@ -281,7 -281,6 +281,6 @@@ static int hdm_add_padding(struct most_
        struct most_channel_config *conf = &mdev->conf[channel];
        unsigned int frame_size = get_stream_frame_size(conf);
        unsigned int j, num_frames;
-       u16 rd_addr, wr_addr;
  
        if (!frame_size)
                return -EIO;
                return -EIO;
        }
  
-       for (j = 1; j < num_frames; j++) {
-               wr_addr = (num_frames - j) * USB_MTU;
-               rd_addr = (num_frames - j) * frame_size;
-               memmove(mbo->virt_address + wr_addr,
-                       mbo->virt_address + rd_addr,
+       for (j = num_frames - 1; j > 0; j--)
+               memmove(mbo->virt_address + j * USB_MTU,
+                       mbo->virt_address + j * frame_size,
                        frame_size);
-       }
        mbo->buffer_length = num_frames * USB_MTU;
        return 0;
  }
@@@ -490,7 -486,7 +486,7 @@@ static void hdm_write_completion(struc
   * disconnect.  In the interval before the hub driver starts disconnect
   * processing, devices may receive such fault reports for every request.
   *
 - * See <https://www.kernel.org/doc/Documentation/usb/error-codes.txt>
 + * See <https://www.kernel.org/doc/Documentation/driver-api/usb/error-codes.rst>
   */
  static void hdm_read_completion(struct urb *urb)
  {
@@@ -649,8 -645,6 +645,6 @@@ static int hdm_configure_channel(struc
  {
        unsigned int num_frames;
        unsigned int frame_size;
-       unsigned int temp_size;
-       unsigned int tail_space;
        struct most_dev *mdev = to_mdev(iface);
        struct device *dev = &mdev->usb_device->dev;
  
        }
  
        mdev->padding_active[channel] = true;
-       temp_size = conf->buffer_size;
  
        frame_size = get_stream_frame_size(conf);
        if (frame_size == 0 || frame_size > USB_MTU) {
                return -EINVAL;
        }
  
+       num_frames = conf->buffer_size / frame_size;
        if (conf->buffer_size % frame_size) {
-               u16 tmp_val;
-               tmp_val = conf->buffer_size / frame_size;
-               conf->buffer_size = tmp_val * frame_size;
-               dev_notice(dev,
-                          "Channel %d - rounding buffer size to %d bytes, channel config says %d bytes\n",
-                          channel,
-                          conf->buffer_size,
-                          temp_size);
-       }
+               u16 old_size = conf->buffer_size;
  
-       num_frames = conf->buffer_size / frame_size;
-       tail_space = num_frames * (USB_MTU - frame_size);
-       temp_size += tail_space;
+               conf->buffer_size = num_frames * frame_size;
+               dev_warn(dev, "%s: fixed buffer size (%d -> %d)\n",
+                        mdev->suffix[channel], old_size, conf->buffer_size);
+       }
  
        /* calculate extra length to comply w/ HW padding */
-       conf->extra_len = (DIV_ROUND_UP(temp_size, USB_MTU) * USB_MTU)
-                         - conf->buffer_size;
+       conf->extra_len = num_frames * (USB_MTU - frame_size);
  exit:
        mdev->conf[channel] = *conf;
        if (conf->data_type == MOST_CH_ASYNC) {
@@@ -1018,7 -1005,7 +1005,7 @@@ static ssize_t store_value(struct most_
                err = drci_wr_reg(usb_dev, dci_obj->reg_addr, val);
        else if (!strcmp(name, "sync_ep"))
                err = start_sync_ep(usb_dev, val);
-       else if (!get_static_reg_addr(ro_regs, name, &reg_addr))
+       else if (!get_static_reg_addr(rw_regs, name, &reg_addr))
                err = drci_wr_reg(usb_dev, reg_addr, val);
        else
                return -EFAULT;
index 0000000000000000000000000000000000000000,3b75739593124c0f90fba282991c7a42840d4f0c..5e7a61f24f8dc38daea774986696ec6cc1d9ce9d
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,3582 +1,3586 @@@
 -              cfg80211_roamed(padapter->pnetdev
 -                      , notify_channel
 -                      , cur_network->network.MacAddress
 -                      , pmlmepriv->assoc_req+sizeof(struct ieee80211_hdr_3addr)+2
 -                      , pmlmepriv->assoc_req_len-sizeof(struct ieee80211_hdr_3addr)-2
 -                      , pmlmepriv->assoc_rsp+sizeof(struct ieee80211_hdr_3addr)+6
 -                      , pmlmepriv->assoc_rsp_len-sizeof(struct ieee80211_hdr_3addr)-6
 -                      , GFP_ATOMIC);
+ /******************************************************************************
+  *
+  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
+  *
+  * This program is free software; you can redistribute it and/or modify it
+  * under the terms of version 2 of the GNU General Public License as
+  * published by the Free Software Foundation.
+  *
+  * This program is distributed in the hope that it will be useful, but WITHOUT
+  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+  * more details.
+  *
+  ******************************************************************************/
+ #define  _IOCTL_CFG80211_C_
+ #include <drv_types.h>
+ #include <rtw_debug.h>
+ #include <linux/jiffies.h>
+ #include <rtw_wifi_regd.h>
+ #define RTW_MAX_MGMT_TX_CNT (8)
+ #define RTW_SCAN_IE_LEN_MAX      2304
+ #define RTW_MAX_REMAIN_ON_CHANNEL_DURATION 5000 /* ms */
+ #define RTW_MAX_NUM_PMKIDS 4
+ #define RTW_CH_MAX_2G_CHANNEL               14      /* Max channel in 2G band */
+ static const u32 rtw_cipher_suites[] = {
+       WLAN_CIPHER_SUITE_WEP40,
+       WLAN_CIPHER_SUITE_WEP104,
+       WLAN_CIPHER_SUITE_TKIP,
+       WLAN_CIPHER_SUITE_CCMP,
+       WLAN_CIPHER_SUITE_AES_CMAC,
+ };
+ #define RATETAB_ENT(_rate, _rateid, _flags) \
+       {                                                               \
+               .bitrate        = (_rate),                              \
+               .hw_value       = (_rateid),                            \
+               .flags          = (_flags),                             \
+       }
+ #define CHAN2G(_channel, _freq, _flags) {                     \
+       .band                   = NL80211_BAND_2GHZ,            \
+       .center_freq            = (_freq),                      \
+       .hw_value               = (_channel),                   \
+       .flags                  = (_flags),                     \
+       .max_antenna_gain       = 0,                            \
+       .max_power              = 30,                           \
+ }
+ /* if wowlan is not supported, kernel generate a disconnect at each suspend
+  * cf: /net/wireless/sysfs.c, so register a stub wowlan.
+  * Moreover wowlan has to be enabled via a the nl80211_set_wowlan callback.
+  * (from user space, e.g. iw phy0 wowlan enable)
+  */
+ static const struct wiphy_wowlan_support wowlan_stub = {
+       .flags = WIPHY_WOWLAN_ANY,
+       .n_patterns = 0,
+       .pattern_max_len = 0,
+       .pattern_min_len = 0,
+       .max_pkt_offset = 0,
+ };
+ static struct ieee80211_rate rtw_rates[] = {
+       RATETAB_ENT(10,  0x1,   0),
+       RATETAB_ENT(20,  0x2,   0),
+       RATETAB_ENT(55,  0x4,   0),
+       RATETAB_ENT(110, 0x8,   0),
+       RATETAB_ENT(60,  0x10,  0),
+       RATETAB_ENT(90,  0x20,  0),
+       RATETAB_ENT(120, 0x40,  0),
+       RATETAB_ENT(180, 0x80,  0),
+       RATETAB_ENT(240, 0x100, 0),
+       RATETAB_ENT(360, 0x200, 0),
+       RATETAB_ENT(480, 0x400, 0),
+       RATETAB_ENT(540, 0x800, 0),
+ };
+ #define rtw_a_rates           (rtw_rates + 4)
+ #define RTW_A_RATES_NUM       8
+ #define rtw_g_rates           (rtw_rates + 0)
+ #define RTW_G_RATES_NUM       12
+ #define RTW_2G_CHANNELS_NUM 14
+ #define RTW_5G_CHANNELS_NUM 37
+ static struct ieee80211_channel rtw_2ghz_channels[] = {
+       CHAN2G(1, 2412, 0),
+       CHAN2G(2, 2417, 0),
+       CHAN2G(3, 2422, 0),
+       CHAN2G(4, 2427, 0),
+       CHAN2G(5, 2432, 0),
+       CHAN2G(6, 2437, 0),
+       CHAN2G(7, 2442, 0),
+       CHAN2G(8, 2447, 0),
+       CHAN2G(9, 2452, 0),
+       CHAN2G(10, 2457, 0),
+       CHAN2G(11, 2462, 0),
+       CHAN2G(12, 2467, 0),
+       CHAN2G(13, 2472, 0),
+       CHAN2G(14, 2484, 0),
+ };
+ static void rtw_2g_channels_init(struct ieee80211_channel *channels)
+ {
+       memcpy((void*)channels, (void*)rtw_2ghz_channels,
+               sizeof(struct ieee80211_channel)*RTW_2G_CHANNELS_NUM
+       );
+ }
+ static void rtw_2g_rates_init(struct ieee80211_rate *rates)
+ {
+       memcpy(rates, rtw_g_rates,
+               sizeof(struct ieee80211_rate)*RTW_G_RATES_NUM
+       );
+ }
+ static struct ieee80211_supported_band *rtw_spt_band_alloc(
+       enum nl80211_band band
+       )
+ {
+       struct ieee80211_supported_band *spt_band = NULL;
+       int n_channels, n_bitrates;
+       if (band == NL80211_BAND_2GHZ)
+       {
+               n_channels = RTW_2G_CHANNELS_NUM;
+               n_bitrates = RTW_G_RATES_NUM;
+       }
+       else
+       {
+               goto exit;
+       }
+       spt_band = (struct ieee80211_supported_band *)rtw_zmalloc(
+               sizeof(struct ieee80211_supported_band)
+               + sizeof(struct ieee80211_channel)*n_channels
+               + sizeof(struct ieee80211_rate)*n_bitrates
+       );
+       if (!spt_band)
+               goto exit;
+       spt_band->channels = (struct ieee80211_channel*)(((u8 *)spt_band)+sizeof(struct ieee80211_supported_band));
+       spt_band->bitrates = (struct ieee80211_rate*)(((u8 *)spt_band->channels)+sizeof(struct ieee80211_channel)*n_channels);
+       spt_band->band = band;
+       spt_band->n_channels = n_channels;
+       spt_band->n_bitrates = n_bitrates;
+       if (band == NL80211_BAND_2GHZ)
+       {
+               rtw_2g_channels_init(spt_band->channels);
+               rtw_2g_rates_init(spt_band->bitrates);
+       }
+       /* spt_band.ht_cap */
+ exit:
+       return spt_band;
+ }
+ static void rtw_spt_band_free(struct ieee80211_supported_band *spt_band)
+ {
+       u32 size = 0;
+       if (!spt_band)
+               return;
+       if (spt_band->band == NL80211_BAND_2GHZ)
+       {
+               size = sizeof(struct ieee80211_supported_band)
+                       + sizeof(struct ieee80211_channel)*RTW_2G_CHANNELS_NUM
+                       + sizeof(struct ieee80211_rate)*RTW_G_RATES_NUM;
+       }
+       kfree((u8 *)spt_band);
+ }
+ static const struct ieee80211_txrx_stypes
+ rtw_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
+       [NL80211_IFTYPE_ADHOC] = {
+               .tx = 0xffff,
+               .rx = BIT(IEEE80211_STYPE_ACTION >> 4)
+       },
+       [NL80211_IFTYPE_STATION] = {
+               .tx = 0xffff,
+               .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
+               BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
+       },
+       [NL80211_IFTYPE_AP] = {
+               .tx = 0xffff,
+               .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
+               BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
+               BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
+               BIT(IEEE80211_STYPE_DISASSOC >> 4) |
+               BIT(IEEE80211_STYPE_AUTH >> 4) |
+               BIT(IEEE80211_STYPE_DEAUTH >> 4) |
+               BIT(IEEE80211_STYPE_ACTION >> 4)
+       },
+       [NL80211_IFTYPE_AP_VLAN] = {
+               /* copy AP */
+               .tx = 0xffff,
+               .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
+               BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
+               BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
+               BIT(IEEE80211_STYPE_DISASSOC >> 4) |
+               BIT(IEEE80211_STYPE_AUTH >> 4) |
+               BIT(IEEE80211_STYPE_DEAUTH >> 4) |
+               BIT(IEEE80211_STYPE_ACTION >> 4)
+       },
+       [NL80211_IFTYPE_P2P_CLIENT] = {
+               .tx = 0xffff,
+               .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
+               BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
+       },
+       [NL80211_IFTYPE_P2P_GO] = {
+               .tx = 0xffff,
+               .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
+               BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
+               BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
+               BIT(IEEE80211_STYPE_DISASSOC >> 4) |
+               BIT(IEEE80211_STYPE_AUTH >> 4) |
+               BIT(IEEE80211_STYPE_DEAUTH >> 4) |
+               BIT(IEEE80211_STYPE_ACTION >> 4)
+       },
+ };
+ static int rtw_ieee80211_channel_to_frequency(int chan, int band)
+ {
+       /* see 802.11 17.3.8.3.2 and Annex J
+       * there are overlapping channel numbers in 5GHz and 2GHz bands */
+       if (band == NL80211_BAND_2GHZ) {
+               if (chan == 14)
+                       return 2484;
+              else if (chan < 14)
+                       return 2407 + chan * 5;
+       }
+       return 0; /* not supported */
+ }
+ static u64 rtw_get_systime_us(void)
+ {
+       struct timespec ts;
+       get_monotonic_boottime(&ts);
+       return ((u64)ts.tv_sec*1000000) + ts.tv_nsec / 1000;
+ }
+ #define MAX_BSSINFO_LEN 1000
+ struct cfg80211_bss *rtw_cfg80211_inform_bss(struct adapter *padapter, struct wlan_network *pnetwork)
+ {
+       struct ieee80211_channel *notify_channel;
+       struct cfg80211_bss *bss = NULL;
+       /* struct ieee80211_supported_band *band; */
+       u16 channel;
+       u32 freq;
+       u64 notify_timestamp;
+       u16 notify_capability;
+       u16 notify_interval;
+       u8 *notify_ie;
+       size_t notify_ielen;
+       s32 notify_signal;
+       u8 *buf = NULL, *pbuf;
+       size_t len, bssinf_len = 0;
+       struct ieee80211_hdr *pwlanhdr;
+       __le16 *fctrl;
+       u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+       struct wireless_dev *wdev = padapter->rtw_wdev;
+       struct wiphy *wiphy = wdev->wiphy;
+       struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+       /* DBG_8192C("%s\n", __func__); */
+       bssinf_len = pnetwork->network.IELength+sizeof (struct ieee80211_hdr_3addr);
+       if (bssinf_len > MAX_BSSINFO_LEN) {
+               DBG_871X("%s IE Length too long > %d byte\n", __func__, MAX_BSSINFO_LEN);
+               goto exit;
+       }
+       {
+               u16 wapi_len = 0;
+               if (rtw_get_wapi_ie(pnetwork->network.IEs, pnetwork->network.IELength, NULL, &wapi_len)>0)
+               {
+                       if (wapi_len > 0)
+                       {
+                               DBG_871X("%s, no support wapi!\n", __func__);
+                               goto exit;
+                       }
+               }
+       }
+       /* To reduce PBC Overlap rate */
+       /* spin_lock_bh(&pwdev_priv->scan_req_lock); */
+       if (adapter_wdev_data(padapter)->scan_request != NULL)
+       {
+               u8 *psr = NULL, sr = 0;
+               struct ndis_802_11_ssid *pssid = &pnetwork->network.Ssid;
+               struct cfg80211_scan_request *request = adapter_wdev_data(padapter)->scan_request;
+               struct cfg80211_ssid *ssids = request->ssids;
+               u32 wpsielen = 0;
+               u8 *wpsie = NULL;
+               wpsie = rtw_get_wps_ie(pnetwork->network.IEs+_FIXED_IE_LENGTH_, pnetwork->network.IELength-_FIXED_IE_LENGTH_, NULL, &wpsielen);
+               if (wpsie && wpsielen>0)
+                       psr = rtw_get_wps_attr_content(wpsie,  wpsielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
+               if (sr != 0)
+               {
+                       if (request->n_ssids == 1 && request->n_channels == 1) /*  it means under processing WPS */
+                       {
+                               DBG_8192C("ssid =%s, len =%d\n", pssid->Ssid, pssid->SsidLength);
+                               if (ssids[0].ssid_len == 0) {
+                               }
+                               else if (pssid->SsidLength == ssids[0].ssid_len &&
+                                       !memcmp(pssid->Ssid, ssids[0].ssid, ssids[0].ssid_len))
+                               {
+                                       DBG_871X("%s, got sr and ssid match!\n", __func__);
+                               }
+                               else
+                               {
+                                       if (psr != NULL)
+                                               *psr = 0; /* clear sr */
+                               }
+                       }
+               }
+       }
+       /* spin_unlock_bh(&pwdev_priv->scan_req_lock); */
+       channel = pnetwork->network.Configuration.DSConfig;
+       freq = rtw_ieee80211_channel_to_frequency(channel, NL80211_BAND_2GHZ);
+       notify_channel = ieee80211_get_channel(wiphy, freq);
+       notify_timestamp = rtw_get_systime_us();
+       notify_interval = le16_to_cpu(*(__le16 *)rtw_get_beacon_interval_from_ie(pnetwork->network.IEs));
+       notify_capability = le16_to_cpu(*(__le16 *)rtw_get_capability_from_ie(pnetwork->network.IEs));
+       notify_ie = pnetwork->network.IEs+_FIXED_IE_LENGTH_;
+       notify_ielen = pnetwork->network.IELength-_FIXED_IE_LENGTH_;
+       /* We've set wiphy's signal_type as CFG80211_SIGNAL_TYPE_MBM: signal strength in mBm (100*dBm) */
+       if (check_fwstate(pmlmepriv, _FW_LINKED) == true &&
+               is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)) {
+               notify_signal = 100*translate_percentage_to_dbm(padapter->recvpriv.signal_strength);/* dbm */
+       } else {
+               notify_signal = 100*translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength);/* dbm */
+       }
+       buf = kzalloc(MAX_BSSINFO_LEN, GFP_ATOMIC);
+       if (!buf)
+               goto exit;
+       pbuf = buf;
+       pwlanhdr = (struct ieee80211_hdr *)pbuf;
+       fctrl = &(pwlanhdr->frame_control);
+       *(fctrl) = 0;
+       SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
+       /* pmlmeext->mgnt_seq++; */
+       if (pnetwork->network.Reserved[0] == 1) { /*  WIFI_BEACON */
+               memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
+               SetFrameSubType(pbuf, WIFI_BEACON);
+       } else {
+               memcpy(pwlanhdr->addr1, myid(&(padapter->eeprompriv)), ETH_ALEN);
+               SetFrameSubType(pbuf, WIFI_PROBERSP);
+       }
+       memcpy(pwlanhdr->addr2, pnetwork->network.MacAddress, ETH_ALEN);
+       memcpy(pwlanhdr->addr3, pnetwork->network.MacAddress, ETH_ALEN);
+       pbuf += sizeof(struct ieee80211_hdr_3addr);
+       len = sizeof (struct ieee80211_hdr_3addr);
+       memcpy(pbuf, pnetwork->network.IEs, pnetwork->network.IELength);
+       len += pnetwork->network.IELength;
+       *((__le64*)pbuf) = cpu_to_le64(notify_timestamp);
+       bss = cfg80211_inform_bss_frame(wiphy, notify_channel, (struct ieee80211_mgmt *)buf,
+               len, notify_signal, GFP_ATOMIC);
+       if (unlikely(!bss)) {
+               DBG_8192C(FUNC_ADPT_FMT" bss NULL\n", FUNC_ADPT_ARG(padapter));
+               goto exit;
+       }
+       cfg80211_put_bss(wiphy, bss);
+       kfree(buf);
+ exit:
+       return bss;
+ }
+ /*
+       Check the given bss is valid by kernel API cfg80211_get_bss()
+       @padapter : the given adapter
+       return true if bss is valid,  false for not found.
+ */
+ int rtw_cfg80211_check_bss(struct adapter *padapter)
+ {
+       struct wlan_bssid_ex  *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
+       struct cfg80211_bss *bss = NULL;
+       struct ieee80211_channel *notify_channel = NULL;
+       u32 freq;
+       if (!(pnetwork) || !(padapter->rtw_wdev))
+               return false;
+       freq = rtw_ieee80211_channel_to_frequency(pnetwork->Configuration.DSConfig, NL80211_BAND_2GHZ);
+       notify_channel = ieee80211_get_channel(padapter->rtw_wdev->wiphy, freq);
+       bss = cfg80211_get_bss(padapter->rtw_wdev->wiphy, notify_channel,
+                       pnetwork->MacAddress, pnetwork->Ssid.Ssid,
+                       pnetwork->Ssid.SsidLength,
+                       WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
+       cfg80211_put_bss(padapter->rtw_wdev->wiphy, bss);
+       return  (bss!= NULL);
+ }
+ void rtw_cfg80211_ibss_indicate_connect(struct adapter *padapter)
+ {
+       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+       struct wlan_network  *cur_network = &(pmlmepriv->cur_network);
+       struct wireless_dev *pwdev = padapter->rtw_wdev;
+       struct wiphy *wiphy = pwdev->wiphy;
+       int freq = (int)cur_network->network.Configuration.DSConfig;
+       struct ieee80211_channel *chan;
+       DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
+       if (pwdev->iftype != NL80211_IFTYPE_ADHOC)
+       {
+               return;
+       }
+       if (!rtw_cfg80211_check_bss(padapter)) {
+               struct wlan_bssid_ex  *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
+               struct wlan_network *scanned = pmlmepriv->cur_network_scanned;
+               if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ==true)
+               {
+                       memcpy(&cur_network->network, pnetwork, sizeof(struct wlan_bssid_ex));
+                       if (!rtw_cfg80211_inform_bss(padapter, cur_network))
+                               DBG_871X(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
+                       else
+                               DBG_871X(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter));
+               }
+               else
+               {
+                       if (scanned == NULL) {
+                               rtw_warn_on(1);
+                               return;
+                       }
+                       if (!memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(struct ndis_802_11_ssid))
+                               && !memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS))
+                       ) {
+                               if (!rtw_cfg80211_inform_bss(padapter, scanned)) {
+                                       DBG_871X(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
+                               } else {
+                                       /* DBG_871X(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter)); */
+                               }
+                       } else {
+                               DBG_871X("scanned & pnetwork compare fail\n");
+                               rtw_warn_on(1);
+                       }
+               }
+               if (!rtw_cfg80211_check_bss(padapter))
+                       DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" BSS not found !!\n", FUNC_ADPT_ARG(padapter));
+       }
+       /* notify cfg80211 that device joined an IBSS */
+       chan = ieee80211_get_channel(wiphy, freq);
+       cfg80211_ibss_joined(padapter->pnetdev, cur_network->network.MacAddress, chan, GFP_ATOMIC);
+ }
+ void rtw_cfg80211_indicate_connect(struct adapter *padapter)
+ {
+       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+       struct wlan_network  *cur_network = &(pmlmepriv->cur_network);
+       struct wireless_dev *pwdev = padapter->rtw_wdev;
+       DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
+       if (pwdev->iftype != NL80211_IFTYPE_STATION
+               && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
+       ) {
+               return;
+       }
+       if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
+               return;
+       {
+               struct wlan_bssid_ex  *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
+               struct wlan_network *scanned = pmlmepriv->cur_network_scanned;
+               /* DBG_871X(FUNC_ADPT_FMT" BSS not found\n", FUNC_ADPT_ARG(padapter)); */
+               if (scanned == NULL) {
+                       rtw_warn_on(1);
+                       goto check_bss;
+               }
+               if (!memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS))
+                       && !memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(struct ndis_802_11_ssid))
+               ) {
+                       if (!rtw_cfg80211_inform_bss(padapter, scanned)) {
+                               DBG_871X(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
+                       } else {
+                               /* DBG_871X(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter)); */
+                       }
+               } else {
+                       DBG_871X("scanned: %s("MAC_FMT"), cur: %s("MAC_FMT")\n",
+                               scanned->network.Ssid.Ssid, MAC_ARG(scanned->network.MacAddress),
+                               pnetwork->Ssid.Ssid, MAC_ARG(pnetwork->MacAddress)
+                       );
+                       rtw_warn_on(1);
+               }
+       }
+ check_bss:
+       if (!rtw_cfg80211_check_bss(padapter))
+               DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" BSS not found !!\n", FUNC_ADPT_ARG(padapter));
+       if (rtw_to_roam(padapter) > 0) {
+               struct wiphy *wiphy = pwdev->wiphy;
+               struct ieee80211_channel *notify_channel;
+               u32 freq;
+               u16 channel = cur_network->network.Configuration.DSConfig;
++              struct cfg80211_roam_info roam_info = {};
+               freq = rtw_ieee80211_channel_to_frequency(channel, NL80211_BAND_2GHZ);
+               notify_channel = ieee80211_get_channel(wiphy, freq);
+               DBG_871X(FUNC_ADPT_FMT" call cfg80211_roamed\n", FUNC_ADPT_ARG(padapter));
 -                                   enum nl80211_iftype type, u32 *flags,
++              roam_info.channel = notify_channel;
++              roam_info.bssid = cur_network->network.MacAddress;
++              roam_info.req_ie =
++                      pmlmepriv->assoc_req+sizeof(struct ieee80211_hdr_3addr)+2;
++              roam_info.req_ie_len =
++                      pmlmepriv->assoc_req_len-sizeof(struct ieee80211_hdr_3addr)-2;
++              roam_info.resp_ie =
++                      pmlmepriv->assoc_rsp+sizeof(struct ieee80211_hdr_3addr)+6;
++              roam_info.resp_ie_len =
++                      pmlmepriv->assoc_rsp_len-sizeof(struct ieee80211_hdr_3addr)-6;
++              cfg80211_roamed(padapter->pnetdev, &roam_info, GFP_ATOMIC);
+       }
+       else
+       {
+               cfg80211_connect_result(padapter->pnetdev, cur_network->network.MacAddress
+                       , pmlmepriv->assoc_req+sizeof(struct ieee80211_hdr_3addr)+2
+                       , pmlmepriv->assoc_req_len-sizeof(struct ieee80211_hdr_3addr)-2
+                       , pmlmepriv->assoc_rsp+sizeof(struct ieee80211_hdr_3addr)+6
+                       , pmlmepriv->assoc_rsp_len-sizeof(struct ieee80211_hdr_3addr)-6
+                       , WLAN_STATUS_SUCCESS, GFP_ATOMIC);
+       }
+ }
+ void rtw_cfg80211_indicate_disconnect(struct adapter *padapter)
+ {
+       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+       struct wireless_dev *pwdev = padapter->rtw_wdev;
+       DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
+       if (pwdev->iftype != NL80211_IFTYPE_STATION
+               && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
+       ) {
+               return;
+       }
+       if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
+               return;
+       if (!padapter->mlmepriv.not_indic_disco) {
+               if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
+                       cfg80211_disconnected(padapter->pnetdev, 0,
+                                             NULL, 0, true, GFP_ATOMIC);
+               } else {
+                       cfg80211_connect_result(padapter->pnetdev, NULL, NULL, 0, NULL, 0,
+                               WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC/*GFP_KERNEL*/);
+               }
+       }
+ }
+ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
+ {
+       int ret = 0;
+       u32 wep_key_idx, wep_key_len;
+       struct sta_info *psta = NULL, *pbcmc_sta = NULL;
+       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+       struct security_priv* psecuritypriv =&(padapter->securitypriv);
+       struct sta_priv *pstapriv = &padapter->stapriv;
+       DBG_8192C("%s\n", __func__);
+       param->u.crypt.err = 0;
+       param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
+       if (param_len !=  sizeof(struct ieee_param) + param->u.crypt.key_len)
+       {
+               ret =  -EINVAL;
+               goto exit;
+       }
+       if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+           param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+           param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
+       {
+               if (param->u.crypt.idx >= WEP_KEYS)
+               {
+                       ret = -EINVAL;
+                       goto exit;
+               }
+       }
+       else
+       {
+               psta = rtw_get_stainfo(pstapriv, param->sta_addr);
+               if (!psta)
+               {
+                       /* ret = -EINVAL; */
+                       DBG_8192C("rtw_set_encryption(), sta has already been removed or never been added\n");
+                       goto exit;
+               }
+       }
+       if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL))
+       {
+               /* todo:clear default encryption keys */
+               DBG_8192C("clear default encryption keys, keyid =%d\n", param->u.crypt.idx);
+               goto exit;
+       }
+       if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL))
+       {
+               DBG_8192C("r871x_set_encryption, crypt.alg = WEP\n");
+               wep_key_idx = param->u.crypt.idx;
+               wep_key_len = param->u.crypt.key_len;
+               DBG_8192C("r871x_set_encryption, wep_key_idx =%d, len =%d\n", wep_key_idx, wep_key_len);
+               if ((wep_key_idx >= WEP_KEYS) || (wep_key_len<= 0))
+               {
+                       ret = -EINVAL;
+                       goto exit;
+               }
+               if (wep_key_len > 0)
+               {
+                       wep_key_len = wep_key_len <= 5 ? 5 : 13;
+               }
+               if (psecuritypriv->bWepDefaultKeyIdxSet == 0)
+               {
+                       /* wep default key has not been set, so use this key index as default key. */
+                       psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
+                       psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
+                       psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
+                       psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
+                       if (wep_key_len == 13)
+                       {
+                               psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
+                               psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
+                       }
+                       psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
+               }
+               memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
+               psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
+               rtw_ap_set_wep_key(padapter, param->u.crypt.key, wep_key_len, wep_key_idx, 1);
+               goto exit;
+       }
+       if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) /* group key */ 
+       {
+               if (param->u.crypt.set_tx == 0) /* group key */
+               {
+                       if (strcmp(param->u.crypt.alg, "WEP") == 0)
+                       {
+                               DBG_8192C("%s, set group_key, WEP\n", __func__);
+                               memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
+                               psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
+                               if (param->u.crypt.key_len == 13)
+                               {
+                                               psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
+                               }
+                       }
+                       else if (strcmp(param->u.crypt.alg, "TKIP") == 0)
+                       {
+                               DBG_8192C("%s, set group_key, TKIP\n", __func__);
+                               psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
+                               memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
+                               /* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */
+                               /* set mic key */
+                               memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
+                               memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
+                               psecuritypriv->busetkipkey = true;
+                       }
+                       else if (strcmp(param->u.crypt.alg, "CCMP") == 0)
+                       {
+                               DBG_8192C("%s, set group_key, CCMP\n", __func__);
+                               psecuritypriv->dot118021XGrpPrivacy = _AES_;
+                               memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
+                       }
+                       else
+                       {
+                               DBG_8192C("%s, set group_key, none\n", __func__);
+                               psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
+                       }
+                       psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
+                       psecuritypriv->binstallGrpkey = true;
+                       psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/*  */
+                       rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
+                       pbcmc_sta =rtw_get_bcmc_stainfo(padapter);
+                       if (pbcmc_sta)
+                       {
+                               pbcmc_sta->ieee8021x_blocked = false;
+                               pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;/* rx will use bmc_sta's dot118021XPrivacy */
+                       }
+               }
+               goto exit;
+       }
+       if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) /*  psk/802_1x */
+       {
+               if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
+               {
+                       if (param->u.crypt.set_tx == 1) /* pairwise key */
+                       {
+                               memcpy(psta->dot118021x_UncstKey.skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
+                               if (strcmp(param->u.crypt.alg, "WEP") == 0)
+                               {
+                                       DBG_8192C("%s, set pairwise key, WEP\n", __func__);
+                                       psta->dot118021XPrivacy = _WEP40_;
+                                       if (param->u.crypt.key_len == 13)
+                                       {
+                                               psta->dot118021XPrivacy = _WEP104_;
+                                       }
+                               }
+                               else if (strcmp(param->u.crypt.alg, "TKIP") == 0)
+                               {
+                                       DBG_8192C("%s, set pairwise key, TKIP\n", __func__);
+                                       psta->dot118021XPrivacy = _TKIP_;
+                                       /* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */
+                                       /* set mic key */
+                                       memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
+                                       memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
+                                       psecuritypriv->busetkipkey = true;
+                               }
+                               else if (strcmp(param->u.crypt.alg, "CCMP") == 0)
+                               {
+                                       DBG_8192C("%s, set pairwise key, CCMP\n", __func__);
+                                       psta->dot118021XPrivacy = _AES_;
+                               }
+                               else
+                               {
+                                       DBG_8192C("%s, set pairwise key, none\n", __func__);
+                                       psta->dot118021XPrivacy = _NO_PRIVACY_;
+                               }
+                               rtw_ap_set_pairwise_key(padapter, psta);
+                               psta->ieee8021x_blocked = false;
+                               psta->bpairwise_key_installed = true;
+                       }
+                       else/* group key??? */
+                       {
+                               if (strcmp(param->u.crypt.alg, "WEP") == 0)
+                               {
+                                       memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
+                                       psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
+                                       if (param->u.crypt.key_len == 13)
+                                       {
+                                               psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
+                                       }
+                               }
+                               else if (strcmp(param->u.crypt.alg, "TKIP") == 0)
+                               {
+                                       psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
+                                       memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
+                                       /* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */
+                                       /* set mic key */
+                                       memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
+                                       memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
+                                       psecuritypriv->busetkipkey = true;
+                               }
+                               else if (strcmp(param->u.crypt.alg, "CCMP") == 0)
+                               {
+                                       psecuritypriv->dot118021XGrpPrivacy = _AES_;
+                                       memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
+                               }
+                               else
+                               {
+                                       psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
+                               }
+                               psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
+                               psecuritypriv->binstallGrpkey = true;
+                               psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/*  */
+                               rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
+                               pbcmc_sta =rtw_get_bcmc_stainfo(padapter);
+                               if (pbcmc_sta)
+                               {
+                                       pbcmc_sta->ieee8021x_blocked = false;
+                                       pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;/* rx will use bmc_sta's dot118021XPrivacy */
+                               }
+                       }
+               }
+       }
+ exit:
+       return ret;
+ }
+ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
+ {
+       int ret = 0;
+       u32 wep_key_idx, wep_key_len;
+       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+       struct security_priv *psecuritypriv = &padapter->securitypriv;
+       DBG_8192C("%s\n", __func__);
+       param->u.crypt.err = 0;
+       param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
+       if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
+       {
+               ret =  -EINVAL;
+               goto exit;
+       }
+       if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+           param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+           param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
+       {
+               if (param->u.crypt.idx >= WEP_KEYS
+                       || param->u.crypt.idx >= BIP_MAX_KEYID
+               )
+               {
+                       ret = -EINVAL;
+                       goto exit;
+               }
+       } else {
+               {
+               ret = -EINVAL;
+               goto exit;
+       }
+       }
+       if (strcmp(param->u.crypt.alg, "WEP") == 0)
+       {
+               RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("wpa_set_encryption, crypt.alg = WEP\n"));
+               DBG_8192C("wpa_set_encryption, crypt.alg = WEP\n");
+               wep_key_idx = param->u.crypt.idx;
+               wep_key_len = param->u.crypt.key_len;
+               if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0))
+               {
+                       ret = -EINVAL;
+                       goto exit;
+               }
+               if (psecuritypriv->bWepDefaultKeyIdxSet == 0)
+               {
+                       /* wep default key has not been set, so use this key index as default key. */
+                       wep_key_len = wep_key_len <= 5 ? 5 : 13;
+                       psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
+                       psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
+                       psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
+                       if (wep_key_len == 13)
+                       {
+                               psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
+                               psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
+                       }
+                       psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
+               }
+               memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
+               psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
+               rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0, true);
+               goto exit;
+       }
+       if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) /*  802_1x */
+       {
+               struct sta_info * psta,*pbcmc_sta;
+               struct sta_priv * pstapriv = &padapter->stapriv;
+               /* DBG_8192C("%s, : dot11AuthAlgrthm == dot11AuthAlgrthm_8021X\n", __func__); */
+               if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == true) /* sta mode */
+               {
+                       psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
+                       if (psta == NULL) {
+                               /* DEBUG_ERR(("Set wpa_set_encryption: Obtain Sta_info fail\n")); */
+                               DBG_8192C("%s, : Obtain Sta_info fail\n", __func__);
+                       }
+                       else
+                       {
+                               /* Jeff: don't disable ieee8021x_blocked while clearing key */
+                               if (strcmp(param->u.crypt.alg, "none") != 0)
+                                       psta->ieee8021x_blocked = false;
+                               if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
+                                               (padapter->securitypriv.ndisencryptstatus ==  Ndis802_11Encryption3Enabled))
+                               {
+                                       psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
+                               }
+                               if (param->u.crypt.set_tx == 1)/* pairwise key */
+                               {
+                                       DBG_8192C("%s, : param->u.crypt.set_tx == 1\n", __func__);
+                                       memcpy(psta->dot118021x_UncstKey.skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
+                                       if (strcmp(param->u.crypt.alg, "TKIP") == 0)/* set mic key */
+                                       {
+                                               /* DEBUG_ERR(("\nset key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len)); */
+                                               memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
+                                               memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
+                                               padapter->securitypriv.busetkipkey =false;
+                                               /* _set_timer(&padapter->securitypriv.tkip_timer, 50); */
+                                       }
+                                       /* DEBUG_ERR((" param->u.crypt.key_len =%d\n", param->u.crypt.key_len)); */
+                                       DBG_871X(" ~~~~set sta key:unicastkey\n");
+                                       rtw_setstakey_cmd(padapter, psta, true, true);
+                               }
+                               else/* group key */
+                               {
+                                       if (strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0)
+                                       {
+                                               memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
+                                               memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[16]), 8);
+                                               memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[24]), 8);
+                                               padapter->securitypriv.binstallGrpkey = true;
+                                               /* DEBUG_ERR((" param->u.crypt.key_len =%d\n", param->u.crypt.key_len)); */
+                                               DBG_871X(" ~~~~set sta key:groupkey\n");
+                                               padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
+                                               rtw_set_key(padapter,&padapter->securitypriv, param->u.crypt.idx, 1, true);
+                                       }
+                                       else if (strcmp(param->u.crypt.alg, "BIP") == 0)
+                                       {
+                                               /* DBG_871X("BIP key_len =%d , index =%d @@@@@@@@@@@@@@@@@@\n", param->u.crypt.key_len, param->u.crypt.idx); */
+                                               /* save the IGTK key, length 16 bytes */
+                                               memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
+                                               /*DBG_871X("IGTK key below:\n");
+                                               for (no = 0;no<16;no++)
+                                                       printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]);
+                                               DBG_871X("\n");*/
+                                               padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx;
+                                               padapter->securitypriv.binstallBIPkey = true;
+                                               DBG_871X(" ~~~~set sta key:IGKT\n");
+                                       }
+                               }
+                       }
+                       pbcmc_sta =rtw_get_bcmc_stainfo(padapter);
+                       if (pbcmc_sta == NULL)
+                       {
+                               /* DEBUG_ERR(("Set OID_802_11_ADD_KEY: bcmc stainfo is null\n")); */
+                       }
+                       else
+                       {
+                               /* Jeff: don't disable ieee8021x_blocked while clearing key */
+                               if (strcmp(param->u.crypt.alg, "none") != 0)
+                                       pbcmc_sta->ieee8021x_blocked = false;
+                               if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
+                                               (padapter->securitypriv.ndisencryptstatus ==  Ndis802_11Encryption3Enabled))
+                               {
+                                       pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
+                               }
+                       }
+               }
+               else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) /* adhoc mode */
+               {
+               }
+       }
+ exit:
+       DBG_8192C("%s, ret =%d\n", __func__, ret);
+       return ret;
+ }
+ static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev,
+                               u8 key_index, bool pairwise, const u8 *mac_addr,
+                               struct key_params *params)
+ {
+       char *alg_name;
+       u32 param_len;
+       struct ieee_param *param = NULL;
+       int ret = 0;
+       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
+       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+       DBG_871X(FUNC_NDEV_FMT" adding key for %pM\n", FUNC_NDEV_ARG(ndev), mac_addr);
+       DBG_871X("cipher = 0x%x\n", params->cipher);
+       DBG_871X("key_len = 0x%x\n", params->key_len);
+       DBG_871X("seq_len = 0x%x\n", params->seq_len);
+       DBG_871X("key_index =%d\n", key_index);
+       DBG_871X("pairwise =%d\n", pairwise);
+       param_len = sizeof(struct ieee_param) + params->key_len;
+       param = (struct ieee_param *)rtw_malloc(param_len);
+       if (param == NULL)
+               return -1;
+       memset(param, 0, param_len);
+       param->cmd = IEEE_CMD_SET_ENCRYPTION;
+       memset(param->sta_addr, 0xff, ETH_ALEN);
+       switch (params->cipher) {
+       case IW_AUTH_CIPHER_NONE:
+               /* todo: remove key */
+               /* remove = 1; */
+               alg_name = "none";
+               break;
+       case WLAN_CIPHER_SUITE_WEP40:
+       case WLAN_CIPHER_SUITE_WEP104:
+               alg_name = "WEP";
+               break;
+       case WLAN_CIPHER_SUITE_TKIP:
+               alg_name = "TKIP";
+               break;
+       case WLAN_CIPHER_SUITE_CCMP:
+               alg_name = "CCMP";
+               break;
+       case WLAN_CIPHER_SUITE_AES_CMAC:
+               alg_name = "BIP";
+               break;
+       default:
+               ret = -ENOTSUPP;
+               goto addkey_end;
+       }
+       strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
+       if (!mac_addr || is_broadcast_ether_addr(mac_addr))
+       {
+               param->u.crypt.set_tx = 0; /* for wpa/wpa2 group key */
+       } else {
+               param->u.crypt.set_tx = 1; /* for wpa/wpa2 pairwise key */
+       }
+       param->u.crypt.idx = key_index;
+       if (params->seq_len && params->seq)
+       {
+               memcpy(param->u.crypt.seq, (u8 *)params->seq, params->seq_len);
+       }
+       if (params->key_len && params->key)
+       {
+               param->u.crypt.key_len = params->key_len;
+               memcpy(param->u.crypt.key, (u8 *)params->key, params->key_len);
+       }
+       if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)
+       {
+               ret =  rtw_cfg80211_set_encryption(ndev, param, param_len);
+       }
+       else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
+       {
+               if (mac_addr)
+                       memcpy(param->sta_addr, (void*)mac_addr, ETH_ALEN);
+               ret = rtw_cfg80211_ap_set_encryption(ndev, param, param_len);
+       }
+         else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true
+                 || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)
+         {
+                 /* DBG_8192C("@@@@@@@@@@ fw_state = 0x%x, iftype =%d\n", pmlmepriv->fw_state, rtw_wdev->iftype); */
+                 ret =  rtw_cfg80211_set_encryption(ndev, param, param_len);
+         }
+       else
+       {
+               DBG_8192C("error!\n");
+       }
+ addkey_end:
+       kfree((u8 *)param);
+       return ret;
+ }
+ static int cfg80211_rtw_get_key(struct wiphy *wiphy, struct net_device *ndev,
+                               u8 key_index, bool pairwise, const u8 *mac_addr,
+                               void *cookie,
+                               void (*callback)(void *cookie,
+                                                struct key_params*))
+ {
+       DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
+       return 0;
+ }
+ static int cfg80211_rtw_del_key(struct wiphy *wiphy, struct net_device *ndev,
+                               u8 key_index, bool pairwise, const u8 *mac_addr)
+ {
+       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
+       struct security_priv *psecuritypriv = &padapter->securitypriv;
+       DBG_871X(FUNC_NDEV_FMT" key_index =%d\n", FUNC_NDEV_ARG(ndev), key_index);
+       if (key_index == psecuritypriv->dot11PrivacyKeyIndex)
+       {
+               /* clear the flag of wep default key set. */
+               psecuritypriv->bWepDefaultKeyIdxSet = 0;
+       }
+       return 0;
+ }
+ static int cfg80211_rtw_set_default_key(struct wiphy *wiphy,
+       struct net_device *ndev, u8 key_index
+       , bool unicast, bool multicast
+       )
+ {
+       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
+       struct security_priv *psecuritypriv = &padapter->securitypriv;
+       DBG_871X(FUNC_NDEV_FMT" key_index =%d, unicast =%d, multicast =%d\n",
+                FUNC_NDEV_ARG(ndev), key_index, unicast, multicast);
+       if ((key_index < WEP_KEYS) && ((psecuritypriv->dot11PrivacyAlgrthm == _WEP40_) || (psecuritypriv->dot11PrivacyAlgrthm == _WEP104_))) /* set wep default key */
+       {
+               psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
+               psecuritypriv->dot11PrivacyKeyIndex = key_index;
+               psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
+               psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
+               if (psecuritypriv->dot11DefKeylen[key_index] == 13)
+               {
+                       psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
+                       psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
+               }
+               psecuritypriv->bWepDefaultKeyIdxSet = 1; /* set the flag to represent that wep default key has been set */
+       }
+       return 0;
+ }
+ static int cfg80211_rtw_get_station(struct wiphy *wiphy,
+                                   struct net_device *ndev,
+                               const u8 *mac,
+                               struct station_info *sinfo)
+ {
+       int ret = 0;
+       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
+       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+       struct sta_info *psta = NULL;
+       struct sta_priv *pstapriv = &padapter->stapriv;
+       sinfo->filled = 0;
+       if (!mac) {
+               DBG_871X(FUNC_NDEV_FMT" mac ==%p\n", FUNC_NDEV_ARG(ndev), mac);
+               ret = -ENOENT;
+               goto exit;
+       }
+       psta = rtw_get_stainfo(pstapriv, (u8 *)mac);
+       if (psta == NULL) {
+               DBG_8192C("%s, sta_info is null\n", __func__);
+               ret = -ENOENT;
+               goto exit;
+       }
+ #ifdef DEBUG_CFG80211
+       DBG_871X(FUNC_NDEV_FMT" mac ="MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(mac));
+ #endif
+       /* for infra./P2PClient mode */
+       if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)
+               && check_fwstate(pmlmepriv, _FW_LINKED)
+       )
+       {
+               struct wlan_network  *cur_network = &(pmlmepriv->cur_network);
+               if (memcmp((u8 *)mac, cur_network->network.MacAddress, ETH_ALEN)) {
+                       DBG_871X("%s, mismatch bssid ="MAC_FMT"\n", __func__, MAC_ARG(cur_network->network.MacAddress));
+                       ret = -ENOENT;
+                       goto exit;
+               }
+               sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
+               sinfo->signal = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);
+               sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
+               sinfo->txrate.legacy = rtw_get_cur_max_rate(padapter);
+               sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS);
+               sinfo->rx_packets = sta_rx_data_pkts(psta);
+               sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS);
+               sinfo->tx_packets = psta->sta_stats.tx_pkts;
+       }
+       /* for Ad-Hoc/AP mode */
+       if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)
+                       ||check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)
+                       ||check_fwstate(pmlmepriv, WIFI_AP_STATE))
+               && check_fwstate(pmlmepriv, _FW_LINKED)
+       )
+       {
+               /* TODO: should acquire station info... */
+       }
+ exit:
+       return ret;
+ }
+ extern int netdev_open(struct net_device *pnetdev);
+ static int cfg80211_rtw_change_iface(struct wiphy *wiphy,
+                                    struct net_device *ndev,
 -              enum nl80211_iftype type, u32 *flags, struct vif_params *params)
++                                   enum nl80211_iftype type,
+                                    struct vif_params *params)
+ {
+       enum nl80211_iftype old_type;
+       enum NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
+       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
+       struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
+       struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+       int ret = 0;
+       u8 change = false;
+       DBG_871X(FUNC_NDEV_FMT" type =%d\n", FUNC_NDEV_ARG(ndev), type);
+       if (adapter_to_dvobj(padapter)->processing_dev_remove == true)
+       {
+               ret = -EPERM;
+               goto exit;
+       }
+       {
+               DBG_871X(FUNC_NDEV_FMT" call netdev_open\n", FUNC_NDEV_ARG(ndev));
+               if (netdev_open(ndev) != 0) {
+                       DBG_871X(FUNC_NDEV_FMT" call netdev_open fail\n", FUNC_NDEV_ARG(ndev));
+                       ret = -EPERM;
+                       goto exit;
+               }
+       }
+       if (_FAIL == rtw_pwr_wakeup(padapter)) {
+               DBG_871X(FUNC_NDEV_FMT" call rtw_pwr_wakeup fail\n", FUNC_NDEV_ARG(ndev));
+               ret = -EPERM;
+               goto exit;
+       }
+       old_type = rtw_wdev->iftype;
+       DBG_871X(FUNC_NDEV_FMT" old_iftype =%d, new_iftype =%d\n",
+               FUNC_NDEV_ARG(ndev), old_type, type);
+       if (old_type != type)
+       {
+               change = true;
+               pmlmeext->action_public_rxseq = 0xffff;
+               pmlmeext->action_public_dialog_token = 0xff;
+       }
+       switch (type) {
+       case NL80211_IFTYPE_ADHOC:
+               networkType = Ndis802_11IBSS;
+               break;
+       case NL80211_IFTYPE_STATION:
+               networkType = Ndis802_11Infrastructure;
+               break;
+       case NL80211_IFTYPE_AP:
+               networkType = Ndis802_11APMode;
+               break;
+       default:
+               ret = -EOPNOTSUPP;
+               goto exit;
+       }
+       rtw_wdev->iftype = type;
+       if (rtw_set_802_11_infrastructure_mode(padapter, networkType) ==false)
+       {
+               rtw_wdev->iftype = old_type;
+               ret = -EPERM;
+               goto exit;
+       }
+       rtw_setopmode_cmd(padapter, networkType, true);
+ exit:
+       DBG_871X(FUNC_NDEV_FMT" ret:%d\n", FUNC_NDEV_ARG(ndev), ret);
+       return ret;
+ }
+ void rtw_cfg80211_indicate_scan_done(struct adapter *adapter, bool aborted)
+ {
+       struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter);
+       struct cfg80211_scan_info info = {
+               .aborted = aborted
+       };
+       spin_lock_bh(&pwdev_priv->scan_req_lock);
+       if (pwdev_priv->scan_request != NULL) {
+               #ifdef DEBUG_CFG80211
+               DBG_871X("%s with scan req\n", __func__);
+               #endif
+               /* avoid WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req); */
+               if (pwdev_priv->scan_request->wiphy != pwdev_priv->rtw_wdev->wiphy)
+               {
+                       DBG_8192C("error wiphy compare\n");
+               }
+               else
+               {
+                       cfg80211_scan_done(pwdev_priv->scan_request, &info);
+               }
+               pwdev_priv->scan_request = NULL;
+       } else {
+               #ifdef DEBUG_CFG80211
+               DBG_871X("%s without scan req\n", __func__);
+               #endif
+       }
+       spin_unlock_bh(&pwdev_priv->scan_req_lock);
+ }
+ void rtw_cfg80211_unlink_bss(struct adapter *padapter, struct wlan_network *pnetwork)
+ {
+       struct wireless_dev *pwdev = padapter->rtw_wdev;
+       struct wiphy *wiphy = pwdev->wiphy;
+       struct cfg80211_bss *bss = NULL;
+       struct wlan_bssid_ex select_network = pnetwork->network;
+       bss = cfg80211_get_bss(wiphy, NULL/*notify_channel*/,
+               select_network.MacAddress, select_network.Ssid.Ssid,
+               select_network.Ssid.SsidLength, 0/*WLAN_CAPABILITY_ESS*/,
+               0/*WLAN_CAPABILITY_ESS*/);
+       if (bss) {
+               cfg80211_unlink_bss(wiphy, bss);
+               DBG_8192C("%s(): cfg80211_unlink %s!! () ", __func__, select_network.Ssid.Ssid);
+               cfg80211_put_bss(padapter->rtw_wdev->wiphy, bss);
+       }
+       return;
+ }
+ void rtw_cfg80211_surveydone_event_callback(struct adapter *padapter)
+ {
+       struct list_head                                        *plist, *phead;
+       struct  mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+       struct __queue *queue   = &(pmlmepriv->scanned_queue);
+       struct  wlan_network    *pnetwork = NULL;
+ #ifdef DEBUG_CFG80211
+       DBG_8192C("%s\n", __func__);
+ #endif
+       spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
+       phead = get_list_head(queue);
+       plist = get_next(phead);
+       while (1)
+       {
+               if (phead == plist)
+                       break;
+               pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
+               /* report network only if the current channel set contains the channel to which this network belongs */
+               if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0
+                       && rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == true
+                       && true == rtw_validate_ssid(&(pnetwork->network.Ssid))
+               )
+               {
+                       /* ev =translate_scan(padapter, a, pnetwork, ev, stop); */
+                       rtw_cfg80211_inform_bss(padapter, pnetwork);
+               }
+               plist = get_next(plist);
+       }
+       spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
+ }
+ static int rtw_cfg80211_set_probe_req_wpsp2pie(struct adapter *padapter, char *buf, int len)
+ {
+       int ret = 0;
+       uint wps_ielen = 0;
+       u8 *wps_ie;
+       struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ #ifdef DEBUG_CFG80211
+       DBG_8192C("%s, ielen =%d\n", __func__, len);
+ #endif
+       if (len>0)
+       {
+               if ((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
+               {
+                       #ifdef DEBUG_CFG80211
+                       DBG_8192C("probe_req_wps_ielen =%d\n", wps_ielen);
+                       #endif
+                       if (pmlmepriv->wps_probe_req_ie)
+                       {
+                               pmlmepriv->wps_probe_req_ie_len = 0;
+                               kfree(pmlmepriv->wps_probe_req_ie);
+                               pmlmepriv->wps_probe_req_ie = NULL;
+                       }
+                       pmlmepriv->wps_probe_req_ie = rtw_malloc(wps_ielen);
+                       if (pmlmepriv->wps_probe_req_ie == NULL) {
+                               DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
+                               return -EINVAL;
+                       }
+                       memcpy(pmlmepriv->wps_probe_req_ie, wps_ie, wps_ielen);
+                       pmlmepriv->wps_probe_req_ie_len = wps_ielen;
+               }
+       }
+       return ret;
+ }
+ static int cfg80211_rtw_scan(struct wiphy *wiphy
+       , struct cfg80211_scan_request *request)
+ {
+       struct net_device *ndev = wdev_to_ndev(request->wdev);
+       int i;
+       u8 _status = false;
+       int ret = 0;
+       struct ndis_802_11_ssid ssid[RTW_SSID_SCAN_AMOUNT];
+       struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT];
+       u8 survey_times =3;
+       u8 survey_times_for_one_ch =6;
+       struct cfg80211_ssid *ssids = request->ssids;
+       int j = 0;
+       bool need_indicate_scan_done = false;
+       struct adapter *padapter;
+       struct rtw_wdev_priv *pwdev_priv;
+       struct mlme_priv *pmlmepriv;
+       if (ndev == NULL) {
+               ret = -EINVAL;
+               goto exit;
+       }
+       padapter = (struct adapter *)rtw_netdev_priv(ndev);
+       pwdev_priv = adapter_wdev_data(padapter);
+       pmlmepriv = &padapter->mlmepriv;
+ /* ifdef DEBUG_CFG80211 */
+       DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
+ /* endif */
+       spin_lock_bh(&pwdev_priv->scan_req_lock);
+       pwdev_priv->scan_request = request;
+       spin_unlock_bh(&pwdev_priv->scan_req_lock);
+       if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
+       {
+ #ifdef DEBUG_CFG80211
+               DBG_871X("%s under WIFI_AP_STATE\n", __func__);
+ #endif
+               if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS|_FW_UNDER_SURVEY|_FW_UNDER_LINKING) == true)
+               {
+                       DBG_8192C("%s, fwstate = 0x%x\n", __func__, pmlmepriv->fw_state);
+                       if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
+                       {
+                               DBG_8192C("AP mode process WPS\n");
+                       }
+                       need_indicate_scan_done = true;
+                       goto check_need_indicate_scan_done;
+               }
+       }
+       rtw_ps_deny(padapter, PS_DENY_SCAN);
+       if (_FAIL == rtw_pwr_wakeup(padapter)) {
+               need_indicate_scan_done = true;
+               goto check_need_indicate_scan_done;
+       }
+       if (request->ie && request->ie_len>0)
+       {
+               rtw_cfg80211_set_probe_req_wpsp2pie(padapter, (u8 *)request->ie, request->ie_len);
+       }
+       if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) {
+               DBG_8192C("%s, fwstate = 0x%x\n", __func__, pmlmepriv->fw_state);
+               need_indicate_scan_done = true;
+               goto check_need_indicate_scan_done;
+       } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) {
+               DBG_8192C("%s, fwstate = 0x%x\n", __func__, pmlmepriv->fw_state);
+               ret = -EBUSY;
+               goto check_need_indicate_scan_done;
+       }
+       if (pmlmepriv->LinkDetectInfo.bBusyTraffic == true)
+       {
+               static unsigned long lastscantime = 0;
+               unsigned long passtime;
+               passtime = jiffies_to_msecs(jiffies - lastscantime);
+               lastscantime = jiffies;
+               if (passtime > 12000)
+               {
+                       DBG_871X("%s: bBusyTraffic == true\n", __func__);
+                       need_indicate_scan_done = true;
+                       goto check_need_indicate_scan_done;
+               }
+       }
+       if (rtw_is_scan_deny(padapter)) {
+               DBG_871X(FUNC_ADPT_FMT  ": scan deny\n", FUNC_ADPT_ARG(padapter));
+               need_indicate_scan_done = true;
+               goto check_need_indicate_scan_done;
+       }
+       memset(ssid, 0, sizeof(struct ndis_802_11_ssid)*RTW_SSID_SCAN_AMOUNT);
+       /* parsing request ssids, n_ssids */
+       for (i = 0; i < request->n_ssids && i < RTW_SSID_SCAN_AMOUNT; i++) {
+               #ifdef DEBUG_CFG80211
+               DBG_8192C("ssid =%s, len =%d\n", ssids[i].ssid, ssids[i].ssid_len);
+               #endif
+               memcpy(ssid[i].Ssid, ssids[i].ssid, ssids[i].ssid_len);
+               ssid[i].SsidLength = ssids[i].ssid_len;
+       }
+       /* parsing channels, n_channels */
+       memset(ch, 0, sizeof(struct rtw_ieee80211_channel)*RTW_CHANNEL_SCAN_AMOUNT);
+       for (i = 0;i<request->n_channels && i<RTW_CHANNEL_SCAN_AMOUNT;i++) {
+               #ifdef DEBUG_CFG80211
+               DBG_871X(FUNC_ADPT_FMT CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(request->channels[i]));
+               #endif
+               ch[i].hw_value = request->channels[i]->hw_value;
+               ch[i].flags = request->channels[i]->flags;
+       }
+       spin_lock_bh(&pmlmepriv->lock);
+       if (request->n_channels == 1) {
+               for (i = 1;i<survey_times_for_one_ch;i++)
+                       memcpy(&ch[i], &ch[0], sizeof(struct rtw_ieee80211_channel));
+               _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, ch, survey_times_for_one_ch);
+       } else if (request->n_channels <= 4) {
+               for (j =request->n_channels-1;j>= 0;j--)
+                       for (i = 0;i<survey_times;i++)
+               {
+                       memcpy(&ch[j*survey_times+i], &ch[j], sizeof(struct rtw_ieee80211_channel));
+               }
+               _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, ch, survey_times * request->n_channels);
+       } else {
+               _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, NULL, 0);
+       }
+       spin_unlock_bh(&pmlmepriv->lock);
+       if (_status == false)
+       {
+               ret = -1;
+       }
+ check_need_indicate_scan_done:
+       if (true == need_indicate_scan_done)
+       {
+               rtw_cfg80211_surveydone_event_callback(padapter);
+               rtw_cfg80211_indicate_scan_done(padapter, false);
+       }
+       rtw_ps_deny_cancel(padapter, PS_DENY_SCAN);
+ exit:
+       return ret;
+ }
+ static int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, u32 changed)
+ {
+       DBG_8192C("%s\n", __func__);
+       return 0;
+ }
+ static int rtw_cfg80211_set_wpa_version(struct security_priv *psecuritypriv, u32 wpa_version)
+ {
+       DBG_8192C("%s, wpa_version =%d\n", __func__, wpa_version);
+       if (!wpa_version) {
+               psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
+               return 0;
+       }
+       if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
+       {
+               psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK;
+       }
+       return 0;
+ }
+ static int rtw_cfg80211_set_auth_type(struct security_priv *psecuritypriv,
+                            enum nl80211_auth_type sme_auth_type)
+ {
+       DBG_8192C("%s, nl80211_auth_type =%d\n", __func__, sme_auth_type);
+       switch (sme_auth_type) {
+       case NL80211_AUTHTYPE_AUTOMATIC:
+               psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
+               break;
+       case NL80211_AUTHTYPE_OPEN_SYSTEM:
+               psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
+               if (psecuritypriv->ndisauthtype>Ndis802_11AuthModeWPA)
+                       psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
+               break;
+       case NL80211_AUTHTYPE_SHARED_KEY:
+               psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
+               psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
+               break;
+       default:
+               psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
+               /* return -ENOTSUPP; */
+       }
+       return 0;
+ }
+ static int rtw_cfg80211_set_cipher(struct security_priv *psecuritypriv, u32 cipher, bool ucast)
+ {
+       u32 ndisencryptstatus = Ndis802_11EncryptionDisabled;
+       u32 *profile_cipher = ucast ? &psecuritypriv->dot11PrivacyAlgrthm :
+               &psecuritypriv->dot118021XGrpPrivacy;
+       DBG_8192C("%s, ucast =%d, cipher = 0x%x\n", __func__, ucast, cipher);
+       if (!cipher) {
+               *profile_cipher = _NO_PRIVACY_;
+               psecuritypriv->ndisencryptstatus = ndisencryptstatus;
+               return 0;
+       }
+       switch (cipher) {
+       case IW_AUTH_CIPHER_NONE:
+               *profile_cipher = _NO_PRIVACY_;
+               ndisencryptstatus = Ndis802_11EncryptionDisabled;
+               break;
+       case WLAN_CIPHER_SUITE_WEP40:
+               *profile_cipher = _WEP40_;
+               ndisencryptstatus = Ndis802_11Encryption1Enabled;
+               break;
+       case WLAN_CIPHER_SUITE_WEP104:
+               *profile_cipher = _WEP104_;
+               ndisencryptstatus = Ndis802_11Encryption1Enabled;
+               break;
+       case WLAN_CIPHER_SUITE_TKIP:
+               *profile_cipher = _TKIP_;
+               ndisencryptstatus = Ndis802_11Encryption2Enabled;
+               break;
+       case WLAN_CIPHER_SUITE_CCMP:
+               *profile_cipher = _AES_;
+               ndisencryptstatus = Ndis802_11Encryption3Enabled;
+               break;
+       default:
+               DBG_8192C("Unsupported cipher: 0x%x\n", cipher);
+               return -ENOTSUPP;
+       }
+       if (ucast)
+       {
+               psecuritypriv->ndisencryptstatus = ndisencryptstatus;
+               /* if (psecuritypriv->dot11PrivacyAlgrthm >= _AES_) */
+               /*      psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK; */
+       }
+       return 0;
+ }
+ static int rtw_cfg80211_set_key_mgt(struct security_priv *psecuritypriv, u32 key_mgt)
+ {
+       DBG_8192C("%s, key_mgt = 0x%x\n", __func__, key_mgt);
+       if (key_mgt == WLAN_AKM_SUITE_8021X)
+               /* auth_type = UMAC_AUTH_TYPE_8021X; */
+               psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
+       else if (key_mgt == WLAN_AKM_SUITE_PSK) {
+               psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
+       }
+       else {
+               DBG_8192C("Invalid key mgt: 0x%x\n", key_mgt);
+               /* return -EINVAL; */
+       }
+       return 0;
+ }
+ static int rtw_cfg80211_set_wpa_ie(struct adapter *padapter, u8 *pie, size_t ielen)
+ {
+       u8 *buf = NULL, *pos = NULL;
+       int group_cipher = 0, pairwise_cipher = 0;
+       int ret = 0;
+       int wpa_ielen = 0;
+       int wpa2_ielen = 0;
+       u8 *pwpa, *pwpa2;
+       u8 null_addr[]= {0, 0, 0, 0, 0, 0};
+       if (pie == NULL || !ielen) {
+               /* Treat this as normal case, but need to clear WIFI_UNDER_WPS */
+               _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
+               goto exit;
+       }
+       if (ielen > MAX_WPA_IE_LEN+MAX_WPS_IE_LEN+MAX_P2P_IE_LEN) {
+               ret = -EINVAL;
+               goto exit;
+       }
+       buf = rtw_zmalloc(ielen);
+       if (buf == NULL) {
+               ret =  -ENOMEM;
+               goto exit;
+       }
+       memcpy(buf, pie , ielen);
+       /* dump */
+       {
+               int i;
+               DBG_8192C("set wpa_ie(length:%zu):\n", ielen);
+               for (i = 0;i<ielen;i =i+8)
+                       DBG_8192C("0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n", buf[i], buf[i+1], buf[i+2], buf[i+3], buf[i+4], buf[i+5], buf[i+6], buf[i+7]);
+       }
+       pos = buf;
+       if (ielen < RSN_HEADER_LEN) {
+               RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("Ie len too short %d\n", ielen));
+               ret  = -1;
+               goto exit;
+       }
+       pwpa = rtw_get_wpa_ie(buf, &wpa_ielen, ielen);
+       if (pwpa && wpa_ielen>0)
+       {
+               if (rtw_parse_wpa_ie(pwpa, wpa_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
+               {
+                       padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
+                       padapter->securitypriv.ndisauthtype =Ndis802_11AuthModeWPAPSK;
+                       memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0], wpa_ielen+2);
+                       DBG_8192C("got wpa_ie, wpa_ielen:%u\n", wpa_ielen);
+               }
+       }
+       pwpa2 = rtw_get_wpa2_ie(buf, &wpa2_ielen, ielen);
+       if (pwpa2 && wpa2_ielen>0)
+       {
+               if (rtw_parse_wpa2_ie(pwpa2, wpa2_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
+               {
+                       padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
+                       padapter->securitypriv.ndisauthtype =Ndis802_11AuthModeWPA2PSK;
+                       memcpy(padapter->securitypriv.supplicant_ie, &pwpa2[0], wpa2_ielen+2);
+                       DBG_8192C("got wpa2_ie, wpa2_ielen:%u\n", wpa2_ielen);
+               }
+       }
+       if (group_cipher == 0)
+       {
+               group_cipher = WPA_CIPHER_NONE;
+       }
+       if (pairwise_cipher == 0)
+       {
+               pairwise_cipher = WPA_CIPHER_NONE;
+       }
+       switch (group_cipher)
+       {
+               case WPA_CIPHER_NONE:
+                       padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
+                       padapter->securitypriv.ndisencryptstatus =Ndis802_11EncryptionDisabled;
+                       break;
+               case WPA_CIPHER_WEP40:
+                       padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
+                       padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
+                       break;
+               case WPA_CIPHER_TKIP:
+                       padapter->securitypriv.dot118021XGrpPrivacy = _TKIP_;
+                       padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
+                       break;
+               case WPA_CIPHER_CCMP:
+                       padapter->securitypriv.dot118021XGrpPrivacy = _AES_;
+                       padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
+                       break;
+               case WPA_CIPHER_WEP104:
+                       padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
+                       padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
+                       break;
+       }
+       switch (pairwise_cipher)
+       {
+               case WPA_CIPHER_NONE:
+                       padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
+                       padapter->securitypriv.ndisencryptstatus =Ndis802_11EncryptionDisabled;
+                       break;
+               case WPA_CIPHER_WEP40:
+                       padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
+                       padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
+                       break;
+               case WPA_CIPHER_TKIP:
+                       padapter->securitypriv.dot11PrivacyAlgrthm = _TKIP_;
+                       padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
+                       break;
+               case WPA_CIPHER_CCMP:
+                       padapter->securitypriv.dot11PrivacyAlgrthm = _AES_;
+                       padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
+                       break;
+               case WPA_CIPHER_WEP104:
+                       padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
+                       padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
+                       break;
+       }
+       {/* handle wps_ie */
+               uint wps_ielen;
+               u8 *wps_ie;
+               wps_ie = rtw_get_wps_ie(buf, ielen, NULL, &wps_ielen);
+               if (wps_ie && wps_ielen > 0) {
+                       DBG_8192C("got wps_ie, wps_ielen:%u\n", wps_ielen);
+                       padapter->securitypriv.wps_ie_len = wps_ielen<MAX_WPS_IE_LEN?wps_ielen:MAX_WPS_IE_LEN;
+                       memcpy(padapter->securitypriv.wps_ie, wps_ie, padapter->securitypriv.wps_ie_len);
+                       set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
+               } else {
+                       _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
+               }
+       }
+       /* TKIP and AES disallow multicast packets until installing group key */
+       if (padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_
+               || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_
+               || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
+               /* WPS open need to enable multicast */
+               /*  check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == true) */
+               rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);
+       RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
+               ("rtw_set_wpa_ie: pairwise_cipher = 0x%08x padapter->securitypriv.ndisencryptstatus =%d padapter->securitypriv.ndisauthtype =%d\n",
+               pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype));
+ exit:
+       kfree(buf);
+       if (ret)
+               _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
+       return ret;
+ }
+ static int cfg80211_rtw_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
+                                 struct cfg80211_ibss_params *params)
+ {
+       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
+       struct ndis_802_11_ssid ndis_ssid;
+       struct security_priv *psecuritypriv = &padapter->securitypriv;
+       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+       int ret = 0;
+       if (_FAIL == rtw_pwr_wakeup(padapter)) {
+               ret = -EPERM;
+               goto exit;
+       }
+       if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
+               ret = -EPERM;
+               goto exit;
+       }
+       if (!params->ssid || !params->ssid_len)
+       {
+               ret = -EINVAL;
+               goto exit;
+       }
+       if (params->ssid_len > IW_ESSID_MAX_SIZE) {
+               ret = -E2BIG;
+               goto exit;
+       }
+       memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
+       ndis_ssid.SsidLength = params->ssid_len;
+       memcpy(ndis_ssid.Ssid, (u8 *)params->ssid, params->ssid_len);
+       /* DBG_8192C("ssid =%s, len =%zu\n", ndis_ssid.Ssid, params->ssid_len); */
+       psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
+       psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
+       psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
+       psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
+       psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
+       ret = rtw_cfg80211_set_auth_type(psecuritypriv, NL80211_AUTHTYPE_OPEN_SYSTEM);
+       rtw_set_802_11_authentication_mode(padapter, psecuritypriv->ndisauthtype);
+       if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == false)
+       {
+               ret = -1;
+               goto exit;
+       }
+ exit:
+       return ret;
+ }
+ static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
+ {
+       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
+       struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
+       enum nl80211_iftype old_type;
+       int ret = 0;
+       DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
+       padapter->mlmepriv.not_indic_disco = true;
+       old_type = rtw_wdev->iftype;
+       rtw_set_to_roam(padapter, 0);
+       if (check_fwstate(&padapter->mlmepriv, _FW_LINKED))
+       {
+               rtw_scan_abort(padapter);
+               LeaveAllPowerSaveMode(padapter);
+               rtw_wdev->iftype = NL80211_IFTYPE_STATION;
+               if (rtw_set_802_11_infrastructure_mode(padapter, Ndis802_11Infrastructure) ==false)
+               {
+                       rtw_wdev->iftype = old_type;
+                       ret = -EPERM;
+                       goto leave_ibss;
+               }
+               rtw_setopmode_cmd(padapter, Ndis802_11Infrastructure, true);
+       }
+ leave_ibss:
+       padapter->mlmepriv.not_indic_disco = false;
+       return 0;
+ }
+ static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
+                                struct cfg80211_connect_params *sme)
+ {
+       int ret = 0;
+       enum NDIS_802_11_AUTHENTICATION_MODE authmode;
+       struct ndis_802_11_ssid ndis_ssid;
+       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
+       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+       struct security_priv *psecuritypriv = &padapter->securitypriv;
+       padapter->mlmepriv.not_indic_disco = true;
+       DBG_871X("=>"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
+       DBG_871X("privacy =%d, key =%p, key_len =%d, key_idx =%d\n",
+               sme->privacy, sme->key, sme->key_len, sme->key_idx);
+       if (adapter_wdev_data(padapter)->block == true)
+       {
+               ret = -EBUSY;
+               DBG_871X("%s wdev_priv.block is set\n", __func__);
+               goto exit;
+       }
+       rtw_ps_deny(padapter, PS_DENY_JOIN);
+       if (_FAIL == rtw_pwr_wakeup(padapter)) {
+               ret = -EPERM;
+               goto exit;
+       }
+       if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
+               ret = -EPERM;
+               goto exit;
+       }
+       if (!sme->ssid || !sme->ssid_len)
+       {
+               ret = -EINVAL;
+               goto exit;
+       }
+       if (sme->ssid_len > IW_ESSID_MAX_SIZE) {
+               ret = -E2BIG;
+               goto exit;
+       }
+       memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
+       ndis_ssid.SsidLength = sme->ssid_len;
+       memcpy(ndis_ssid.Ssid, (u8 *)sme->ssid, sme->ssid_len);
+       DBG_8192C("ssid =%s, len =%zu\n", ndis_ssid.Ssid, sme->ssid_len);
+       if (sme->bssid)
+               DBG_8192C("bssid ="MAC_FMT"\n", MAC_ARG(sme->bssid));
+       if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) {
+               ret = -EBUSY;
+               DBG_8192C("%s, fw_state = 0x%x, goto exit\n", __func__, pmlmepriv->fw_state);
+               goto exit;
+       }
+       if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) {
+               rtw_scan_abort(padapter);
+       }
+       psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
+       psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
+       psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
+       psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
+       psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
+       ret = rtw_cfg80211_set_wpa_version(psecuritypriv, sme->crypto.wpa_versions);
+       if (ret < 0)
+               goto exit;
+       ret = rtw_cfg80211_set_auth_type(psecuritypriv, sme->auth_type);
+       if (ret < 0)
+               goto exit;
+       DBG_8192C("%s, ie_len =%zu\n", __func__, sme->ie_len);
+       ret = rtw_cfg80211_set_wpa_ie(padapter, (u8 *)sme->ie, sme->ie_len);
+       if (ret < 0)
+               goto exit;
+       if (sme->crypto.n_ciphers_pairwise) {
+               ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.ciphers_pairwise[0], true);
+               if (ret < 0)
+                       goto exit;
+       }
+       /* For WEP Shared auth */
+       if ((psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Shared
+               || psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Auto) && sme->key
+       )
+       {
+               u32 wep_key_idx, wep_key_len, wep_total_len;
+               struct ndis_802_11_wep   *pwep = NULL;
+               DBG_871X("%s(): Shared/Auto WEP\n", __func__);
+               wep_key_idx = sme->key_idx;
+               wep_key_len = sme->key_len;
+               if (sme->key_idx > WEP_KEYS) {
+                       ret = -EINVAL;
+                       goto exit;
+               }
+               if (wep_key_len > 0)
+               {
+                       wep_key_len = wep_key_len <= 5 ? 5 : 13;
+                       wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial);
+                       pwep =(struct ndis_802_11_wep    *) rtw_malloc(wep_total_len);
+                       if (pwep == NULL) {
+                               DBG_871X(" wpa_set_encryption: pwep allocate fail !!!\n");
+                               ret = -ENOMEM;
+                               goto exit;
+                       }
+                       memset(pwep, 0, wep_total_len);
+                       pwep->KeyLength = wep_key_len;
+                       pwep->Length = wep_total_len;
+                       if (wep_key_len == 13)
+                       {
+                               padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
+                               padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
+                       }
+               }
+               else {
+                       ret = -EINVAL;
+                       goto exit;
+               }
+               pwep->KeyIndex = wep_key_idx;
+               pwep->KeyIndex |= 0x80000000;
+               memcpy(pwep->KeyMaterial,  (void *)sme->key, pwep->KeyLength);
+               if (rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL)
+               {
+                       ret = -EOPNOTSUPP ;
+               }
+               kfree((u8 *)pwep);
+               if (ret < 0)
+                       goto exit;
+       }
+       ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.cipher_group, false);
+       if (ret < 0)
+               return ret;
+       if (sme->crypto.n_akm_suites) {
+               ret = rtw_cfg80211_set_key_mgt(psecuritypriv, sme->crypto.akm_suites[0]);
+               if (ret < 0)
+                       goto exit;
+       }
+       authmode = psecuritypriv->ndisauthtype;
+       rtw_set_802_11_authentication_mode(padapter, authmode);
+       /* rtw_set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */
+       if (rtw_set_802_11_connect(padapter, (u8 *)sme->bssid, &ndis_ssid) == false) {
+               ret = -1;
+               goto exit;
+       }
+       DBG_8192C("set ssid:dot11AuthAlgrthm =%d, dot11PrivacyAlgrthm =%d, dot118021XGrpPrivacy =%d\n", psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm, psecuritypriv->dot118021XGrpPrivacy);
+ exit:
+       rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
+       DBG_8192C("<=%s, ret %d\n", __func__, ret);
+       padapter->mlmepriv.not_indic_disco = false;
+       return ret;
+ }
+ static int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev,
+                                  u16 reason_code)
+ {
+       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
+       DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
+       padapter->mlmepriv.not_indic_disco = true;
+       rtw_set_to_roam(padapter, 0);
+       rtw_scan_abort(padapter);
+       LeaveAllPowerSaveMode(padapter);
+       rtw_disassoc_cmd(padapter, 500, false);
+       DBG_871X("%s...call rtw_indicate_disconnect\n", __func__);
+       rtw_indicate_disconnect(padapter);
+       rtw_free_assoc_resources(padapter, 1);
+       rtw_pwr_wakeup(padapter);
+       padapter->mlmepriv.not_indic_disco = false;
+       DBG_871X(FUNC_NDEV_FMT" return 0\n", FUNC_NDEV_ARG(ndev));
+       return 0;
+ }
+ static int cfg80211_rtw_set_txpower(struct wiphy *wiphy,
+       struct wireless_dev *wdev,
+       enum nl80211_tx_power_setting type, int mbm)
+ {
+       DBG_8192C("%s\n", __func__);
+       return 0;
+ }
+ static int cfg80211_rtw_get_txpower(struct wiphy *wiphy,
+       struct wireless_dev *wdev,
+       int *dbm)
+ {
+       DBG_8192C("%s\n", __func__);
+       *dbm = (12);
+       return 0;
+ }
+ inline bool rtw_cfg80211_pwr_mgmt(struct adapter *adapter)
+ {
+       struct rtw_wdev_priv *rtw_wdev_priv = adapter_wdev_data(adapter);
+       return rtw_wdev_priv->power_mgmt;
+ }
+ static int cfg80211_rtw_set_power_mgmt(struct wiphy *wiphy,
+                                      struct net_device *ndev,
+                                      bool enabled, int timeout)
+ {
+       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
+       struct rtw_wdev_priv *rtw_wdev_priv = adapter_wdev_data(padapter);
+       DBG_871X(FUNC_NDEV_FMT" enabled:%u, timeout:%d\n", FUNC_NDEV_ARG(ndev),
+               enabled, timeout);
+       rtw_wdev_priv->power_mgmt = enabled;
+       if (!enabled)
+               LPS_Leave(padapter, "CFG80211_PWRMGMT");
+       return 0;
+ }
+ static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy,
+                                 struct net_device *ndev,
+                                 struct cfg80211_pmksa *pmksa)
+ {
+       u8 index, blInserted = false;
+       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
+       struct security_priv *psecuritypriv = &padapter->securitypriv;
+       u8 strZeroMacAddress[ ETH_ALEN ] = { 0x00 };
+       DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
+       if (!memcmp((u8 *)pmksa->bssid, strZeroMacAddress, ETH_ALEN))
+       {
+               return -EINVAL;
+       }
+       blInserted = false;
+       /* overwrite PMKID */
+       for (index = 0 ; index<NUM_PMKID_CACHE; index++)
+       {
+               if (!memcmp(psecuritypriv->PMKIDList[index].Bssid, (u8 *)pmksa->bssid, ETH_ALEN))
+               { /*  BSSID is matched, the same AP => rewrite with new PMKID. */
+                       DBG_871X(FUNC_NDEV_FMT" BSSID exists in the PMKList.\n", FUNC_NDEV_ARG(ndev));
+                       memcpy(psecuritypriv->PMKIDList[index].PMKID, (u8 *)pmksa->pmkid, WLAN_PMKID_LEN);
+                       psecuritypriv->PMKIDList[index].bUsed = true;
+                       psecuritypriv->PMKIDIndex = index+1;
+                       blInserted = true;
+                       break;
+               }
+       }
+       if (!blInserted)
+       {
+               /*  Find a new entry */
+               DBG_871X(FUNC_NDEV_FMT" Use the new entry index = %d for this PMKID.\n",
+                       FUNC_NDEV_ARG(ndev), psecuritypriv->PMKIDIndex);
+               memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, (u8 *)pmksa->bssid, ETH_ALEN);
+               memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, (u8 *)pmksa->pmkid, WLAN_PMKID_LEN);
+               psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = true;
+               psecuritypriv->PMKIDIndex++ ;
+               if (psecuritypriv->PMKIDIndex == 16)
+               {
+                       psecuritypriv->PMKIDIndex = 0;
+               }
+       }
+       return 0;
+ }
+ static int cfg80211_rtw_del_pmksa(struct wiphy *wiphy,
+                                 struct net_device *ndev,
+                                 struct cfg80211_pmksa *pmksa)
+ {
+       u8 index, bMatched = false;
+       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
+       struct security_priv *psecuritypriv = &padapter->securitypriv;
+       DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
+       for (index = 0 ; index<NUM_PMKID_CACHE; index++)
+       {
+               if (!memcmp(psecuritypriv->PMKIDList[index].Bssid, (u8 *)pmksa->bssid, ETH_ALEN))
+               { /*  BSSID is matched, the same AP => Remove this PMKID information and reset it. */
+                       memset(psecuritypriv->PMKIDList[index].Bssid, 0x00, ETH_ALEN);
+                       memset(psecuritypriv->PMKIDList[index].PMKID, 0x00, WLAN_PMKID_LEN);
+                       psecuritypriv->PMKIDList[index].bUsed = false;
+                       bMatched = true;
+                       break;
+               }
+       }
+       if (false == bMatched)
+       {
+               DBG_871X(FUNC_NDEV_FMT" do not have matched BSSID\n"
+                       , FUNC_NDEV_ARG(ndev));
+               return -EINVAL;
+       }
+       return 0;
+ }
+ static int cfg80211_rtw_flush_pmksa(struct wiphy *wiphy,
+                                   struct net_device *ndev)
+ {
+       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
+       struct security_priv *psecuritypriv = &padapter->securitypriv;
+       DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
+       memset(&psecuritypriv->PMKIDList[ 0 ], 0x00, sizeof(RT_PMKID_LIST) * NUM_PMKID_CACHE);
+       psecuritypriv->PMKIDIndex = 0;
+       return 0;
+ }
+ void rtw_cfg80211_indicate_sta_assoc(struct adapter *padapter, u8 *pmgmt_frame, uint frame_len)
+ {
+       struct net_device *ndev = padapter->pnetdev;
+       DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
+       {
+               struct station_info sinfo;
+               u8 ie_offset;
+               if (GetFrameSubType(pmgmt_frame) == WIFI_ASSOCREQ)
+                       ie_offset = _ASOCREQ_IE_OFFSET_;
+               else /*  WIFI_REASSOCREQ */
+                       ie_offset = _REASOCREQ_IE_OFFSET_;
+               sinfo.filled = 0;
+               sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset;
+               sinfo.assoc_req_ies_len = frame_len - WLAN_HDR_A3_LEN - ie_offset;
+               cfg80211_new_sta(ndev, GetAddr2Ptr(pmgmt_frame), &sinfo, GFP_ATOMIC);
+       }
+ }
+ void rtw_cfg80211_indicate_sta_disassoc(struct adapter *padapter, unsigned char *da, unsigned short reason)
+ {
+       struct net_device *ndev = padapter->pnetdev;
+       DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
+       cfg80211_del_sta(ndev, da, GFP_ATOMIC);
+ }
+ static int rtw_cfg80211_monitor_if_open(struct net_device *ndev)
+ {
+       int ret = 0;
+       DBG_8192C("%s\n", __func__);
+       return ret;
+ }
+ static int rtw_cfg80211_monitor_if_close(struct net_device *ndev)
+ {
+       int ret = 0;
+       DBG_8192C("%s\n", __func__);
+       return ret;
+ }
+ static int rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff *skb, struct net_device *ndev)
+ {
+       int ret = 0;
+       int rtap_len;
+       int qos_len = 0;
+       int dot11_hdr_len = 24;
+       int snap_len = 6;
+       unsigned char *pdata;
+       u16 frame_control;
+       unsigned char src_mac_addr[6];
+       unsigned char dst_mac_addr[6];
+       struct ieee80211_hdr *dot11_hdr;
+       struct ieee80211_radiotap_header *rtap_hdr;
+       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
+       DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
+       if (!skb)
+               goto fail;
+       rtw_mstat_update(MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, skb->truesize);
+       if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
+               goto fail;
+       rtap_hdr = (struct ieee80211_radiotap_header *)skb->data;
+       if (unlikely(rtap_hdr->it_version))
+               goto fail;
+       rtap_len = ieee80211_get_radiotap_len(skb->data);
+       if (unlikely(skb->len < rtap_len))
+               goto fail;
+       if (rtap_len != 14)
+       {
+               DBG_8192C("radiotap len (should be 14): %d\n", rtap_len);
+               goto fail;
+       }
+       /* Skip the ratio tap header */
+       skb_pull(skb, rtap_len);
+       dot11_hdr = (struct ieee80211_hdr *)skb->data;
+       frame_control = le16_to_cpu(dot11_hdr->frame_control);
+       /* Check if the QoS bit is set */
+       if ((frame_control & RTW_IEEE80211_FCTL_FTYPE) == RTW_IEEE80211_FTYPE_DATA) {
+               /* Check if this ia a Wireless Distribution System (WDS) frame
+                * which has 4 MAC addresses
+                */
+               if (frame_control & 0x0080)
+                       qos_len = 2;
+               if ((frame_control & 0x0300) == 0x0300)
+                       dot11_hdr_len += 6;
+               memcpy(dst_mac_addr, dot11_hdr->addr1, sizeof(dst_mac_addr));
+               memcpy(src_mac_addr, dot11_hdr->addr2, sizeof(src_mac_addr));
+               /* Skip the 802.11 header, QoS (if any) and SNAP, but leave spaces for
+                * for two MAC addresses
+                */
+               skb_pull(skb, dot11_hdr_len + qos_len + snap_len - sizeof(src_mac_addr) * 2);
+               pdata = (unsigned char*)skb->data;
+               memcpy(pdata, dst_mac_addr, sizeof(dst_mac_addr));
+               memcpy(pdata + sizeof(dst_mac_addr), src_mac_addr, sizeof(src_mac_addr));
+               DBG_8192C("should be eapol packet\n");
+               /* Use the real net device to transmit the packet */
+               ret = _rtw_xmit_entry(skb, padapter->pnetdev);
+               return ret;
+       }
+       else if ((frame_control & (RTW_IEEE80211_FCTL_FTYPE|RTW_IEEE80211_FCTL_STYPE))
+               == (RTW_IEEE80211_FTYPE_MGMT|RTW_IEEE80211_STYPE_ACTION)
+       )
+       {
+               /* only for action frames */
+               struct xmit_frame               *pmgntframe;
+               struct pkt_attrib       *pattrib;
+               unsigned char *pframe;
+               /* u8 category, action, OUI_Subtype, dialogToken = 0; */
+               /* unsigned char *frame_body; */
+               struct ieee80211_hdr *pwlanhdr;
+               struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
+               struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+               u8 *buf = skb->data;
+               u32 len = skb->len;
+               u8 category, action;
+               if (rtw_action_frame_parse(buf, len, &category, &action) == false) {
+                       DBG_8192C(FUNC_NDEV_FMT" frame_control:0x%x\n", FUNC_NDEV_ARG(ndev),
+                               le16_to_cpu(((struct ieee80211_hdr_3addr *)buf)->frame_control));
+                       goto fail;
+               }
+               DBG_8192C("RTW_Tx:da ="MAC_FMT" via "FUNC_NDEV_FMT"\n",
+                       MAC_ARG(GetAddr1Ptr(buf)), FUNC_NDEV_ARG(ndev));
+               if (category == RTW_WLAN_CATEGORY_PUBLIC)
+                       DBG_871X("RTW_Tx:%s\n", action_public_str(action));
+               else
+                       DBG_871X("RTW_Tx:category(%u), action(%u)\n", category, action);
+               /* starting alloc mgmt frame to dump it */
+               if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
+               {
+                       goto fail;
+               }
+               /* update attribute */
+               pattrib = &pmgntframe->attrib;
+               update_mgntframe_attrib(padapter, pattrib);
+               pattrib->retry_ctrl = false;
+               memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
+               pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
+               memcpy(pframe, (void*)buf, len);
+               pattrib->pktlen = len;
+               pwlanhdr = (struct ieee80211_hdr *)pframe;
+               /* update seq number */
+               pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
+               pattrib->seqnum = pmlmeext->mgnt_seq;
+               pmlmeext->mgnt_seq++;
+               pattrib->last_txcmdsz = pattrib->pktlen;
+               dump_mgntframe(padapter, pmgntframe);
+       }
+       else
+       {
+               DBG_8192C("frame_control = 0x%x\n", frame_control & (RTW_IEEE80211_FCTL_FTYPE|RTW_IEEE80211_FCTL_STYPE));
+       }
+ fail:
+       dev_kfree_skb_any(skb);
+       return 0;
+ }
+ static int rtw_cfg80211_monitor_if_set_mac_address(struct net_device *ndev, void *addr)
+ {
+       int ret = 0;
+       DBG_8192C("%s\n", __func__);
+       return ret;
+ }
+ static const struct net_device_ops rtw_cfg80211_monitor_if_ops = {
+       .ndo_open = rtw_cfg80211_monitor_if_open,
+        .ndo_stop = rtw_cfg80211_monitor_if_close,
+        .ndo_start_xmit = rtw_cfg80211_monitor_if_xmit_entry,
+        .ndo_set_mac_address = rtw_cfg80211_monitor_if_set_mac_address,
+ };
+ static int rtw_cfg80211_add_monitor_if (struct adapter *padapter, char *name, struct net_device **ndev)
+ {
+       int ret = 0;
+       struct net_device* mon_ndev = NULL;
+       struct wireless_dev* mon_wdev = NULL;
+       struct rtw_netdev_priv_indicator *pnpi;
+       struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
+       if (!name) {
+               DBG_871X(FUNC_ADPT_FMT" without specific name\n", FUNC_ADPT_ARG(padapter));
+               ret = -EINVAL;
+               goto out;
+       }
+       if (pwdev_priv->pmon_ndev) {
+               DBG_871X(FUNC_ADPT_FMT" monitor interface exist: "NDEV_FMT"\n",
+                       FUNC_ADPT_ARG(padapter), NDEV_ARG(pwdev_priv->pmon_ndev));
+               ret = -EBUSY;
+               goto out;
+       }
+       mon_ndev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
+       if (!mon_ndev) {
+               DBG_871X(FUNC_ADPT_FMT" allocate ndev fail\n", FUNC_ADPT_ARG(padapter));
+               ret = -ENOMEM;
+               goto out;
+       }
+       mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP;
+       strncpy(mon_ndev->name, name, IFNAMSIZ);
+       mon_ndev->name[IFNAMSIZ - 1] = 0;
+       mon_ndev->destructor = rtw_ndev_destructor;
+       mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops;
+       pnpi = netdev_priv(mon_ndev);
+       pnpi->priv = padapter;
+       pnpi->sizeof_priv = sizeof(struct adapter);
+       /*  wdev */
+       mon_wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev));
+       if (!mon_wdev) {
+               DBG_871X(FUNC_ADPT_FMT" allocate mon_wdev fail\n", FUNC_ADPT_ARG(padapter));
+               ret = -ENOMEM;
+               goto out;
+       }
+       mon_wdev->wiphy = padapter->rtw_wdev->wiphy;
+       mon_wdev->netdev = mon_ndev;
+       mon_wdev->iftype = NL80211_IFTYPE_MONITOR;
+       mon_ndev->ieee80211_ptr = mon_wdev;
+       ret = register_netdevice(mon_ndev);
+       if (ret) {
+               goto out;
+       }
+       *ndev = pwdev_priv->pmon_ndev = mon_ndev;
+       memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ+1);
+ out:
+       if (ret && mon_wdev) {
+               kfree((u8 *)mon_wdev);
+               mon_wdev = NULL;
+       }
+       if (ret && mon_ndev) {
+               free_netdev(mon_ndev);
+               *ndev = mon_ndev = NULL;
+       }
+       return ret;
+ }
+ static struct wireless_dev *
+       cfg80211_rtw_add_virtual_intf(
+               struct wiphy *wiphy,
+               const char *name,
+               unsigned char name_assign_type,
 -      wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
++              enum nl80211_iftype type, struct vif_params *params)
+ {
+       int ret = 0;
+       struct net_device* ndev = NULL;
+       struct adapter *padapter = wiphy_to_adapter(wiphy);
+       DBG_871X(FUNC_ADPT_FMT " wiphy:%s, name:%s, type:%d\n",
+               FUNC_ADPT_ARG(padapter), wiphy_name(wiphy), name, type);
+       switch (type) {
+       case NL80211_IFTYPE_ADHOC:
+       case NL80211_IFTYPE_AP_VLAN:
+       case NL80211_IFTYPE_WDS:
+       case NL80211_IFTYPE_MESH_POINT:
+               ret = -ENODEV;
+               break;
+       case NL80211_IFTYPE_MONITOR:
+               ret = rtw_cfg80211_add_monitor_if(padapter, (char *)name, &ndev);
+               break;
+       case NL80211_IFTYPE_P2P_CLIENT:
+       case NL80211_IFTYPE_STATION:
+               ret = -ENODEV;
+               break;
+       case NL80211_IFTYPE_P2P_GO:
+       case NL80211_IFTYPE_AP:
+               ret = -ENODEV;
+               break;
+       default:
+               ret = -ENODEV;
+               DBG_871X("Unsupported interface type\n");
+               break;
+       }
+       DBG_871X(FUNC_ADPT_FMT" ndev:%p, ret:%d\n", FUNC_ADPT_ARG(padapter), ndev, ret);
+       return ndev ? ndev->ieee80211_ptr : ERR_PTR(ret);
+ }
+ static int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy,
+       struct wireless_dev *wdev
+ )
+ {
+       struct net_device *ndev = wdev_to_ndev(wdev);
+       int ret = 0;
+       struct adapter *adapter;
+       struct rtw_wdev_priv *pwdev_priv;
+       if (!ndev) {
+               ret = -EINVAL;
+               goto exit;
+       }
+       adapter = (struct adapter *)rtw_netdev_priv(ndev);
+       pwdev_priv = adapter_wdev_data(adapter);
+       unregister_netdevice(ndev);
+       if (ndev == pwdev_priv->pmon_ndev) {
+               pwdev_priv->pmon_ndev = NULL;
+               pwdev_priv->ifname_mon[0] = '\0';
+               DBG_871X(FUNC_NDEV_FMT" remove monitor interface\n", FUNC_NDEV_ARG(ndev));
+       }
+ exit:
+       return ret;
+ }
+ static int rtw_add_beacon(struct adapter *adapter, const u8 *head, size_t head_len, const u8 *tail, size_t tail_len)
+ {
+       int ret = 0;
+       u8 *pbuf = NULL;
+       uint len, wps_ielen = 0;
+       struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
+       DBG_8192C("%s beacon_head_len =%zu, beacon_tail_len =%zu\n", __func__, head_len, tail_len);
+       if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
+               return -EINVAL;
+       if (head_len<24)
+               return -EINVAL;
+       pbuf = rtw_zmalloc(head_len+tail_len);
+       if (!pbuf)
+               return -ENOMEM;
+       memcpy(pbuf, (void *)head+24, head_len-24);/*  24 =beacon header len. */
+       memcpy(pbuf+head_len-24, (void *)tail, tail_len);
+       len = head_len+tail_len-24;
+       /* check wps ie if inclued */
+       if (rtw_get_wps_ie(pbuf+_FIXED_IE_LENGTH_, len-_FIXED_IE_LENGTH_, NULL, &wps_ielen))
+               DBG_8192C("add bcn, wps_ielen =%d\n", wps_ielen);
+       /* pbss_network->IEs will not include p2p_ie, wfd ie */
+       rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, P2P_OUI, 4);
+       rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, WFD_OUI, 4);
+       if (rtw_check_beacon_data(adapter, pbuf,  len) == _SUCCESS)
+       {
+               ret = 0;
+       }
+       else
+       {
+               ret = -EINVAL;
+       }
+       kfree(pbuf);
+       return ret;
+ }
+ static int cfg80211_rtw_start_ap(struct wiphy *wiphy, struct net_device *ndev,
+                                                               struct cfg80211_ap_settings *settings)
+ {
+       int ret = 0;
+       struct adapter *adapter = (struct adapter *)rtw_netdev_priv(ndev);
+       DBG_871X(FUNC_NDEV_FMT" hidden_ssid:%d, auth_type:%d\n", FUNC_NDEV_ARG(ndev),
+               settings->hidden_ssid, settings->auth_type);
+       ret = rtw_add_beacon(adapter, settings->beacon.head, settings->beacon.head_len,
+               settings->beacon.tail, settings->beacon.tail_len);
+       adapter->mlmeextpriv.mlmext_info.hidden_ssid_mode = settings->hidden_ssid;
+       if (settings->ssid && settings->ssid_len) {
+               struct wlan_bssid_ex *pbss_network = &adapter->mlmepriv.cur_network.network;
+               struct wlan_bssid_ex *pbss_network_ext = &adapter->mlmeextpriv.mlmext_info.network;
+               memcpy(pbss_network->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
+               pbss_network->Ssid.SsidLength = settings->ssid_len;
+               memcpy(pbss_network_ext->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
+               pbss_network_ext->Ssid.SsidLength = settings->ssid_len;
+       }
+       return ret;
+ }
+ static int cfg80211_rtw_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
+                                 struct cfg80211_beacon_data *info)
+ {
+       int ret = 0;
+       struct adapter *adapter = (struct adapter *)rtw_netdev_priv(ndev);
+       DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
+       ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len);
+       return ret;
+ }
+ static int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
+ {
+       DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
+       return 0;
+ }
+ static int    cfg80211_rtw_add_station(struct wiphy *wiphy, struct net_device *ndev,
+                               const u8 *mac,
+                       struct station_parameters *params)
+ {
+       DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
+       return 0;
+ }
+ static int cfg80211_rtw_del_station(struct wiphy *wiphy, struct net_device *ndev,
+                                   struct station_del_parameters *params)
+ {
+       int ret = 0;
+       struct list_head        *phead, *plist;
+       u8 updated = false;
+       struct sta_info *psta = NULL;
+       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
+       struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+       struct sta_priv *pstapriv = &padapter->stapriv;
+       const u8 *mac = params->mac;
+       DBG_871X("+"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
+       if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
+       {
+               DBG_8192C("%s, fw_state != FW_LINKED|WIFI_AP_STATE\n", __func__);
+               return -EINVAL;
+       }
+       if (!mac)
+       {
+               DBG_8192C("flush all sta, and cam_entry\n");
+               flush_all_cam_entry(padapter);  /* clear CAM */
+               ret = rtw_sta_flush(padapter);
+               return ret;
+       }
+       DBG_8192C("free sta macaddr =" MAC_FMT "\n", MAC_ARG(mac));
+       if (mac[0] == 0xff && mac[1] == 0xff &&
+           mac[2] == 0xff && mac[3] == 0xff &&
+           mac[4] == 0xff && mac[5] == 0xff)
+       {
+               return -EINVAL;
+       }
+       spin_lock_bh(&pstapriv->asoc_list_lock);
+       phead = &pstapriv->asoc_list;
+       plist = get_next(phead);
+       /* check asoc_queue */
+       while (phead != plist)
+       {
+               psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
+               plist = get_next(plist);
+               if (!memcmp((u8 *)mac, psta->hwaddr, ETH_ALEN))
+               {
+                       if (psta->dot8021xalg == 1 && psta->bpairwise_key_installed == false)
+                       {
+                               DBG_8192C("%s, sta's dot8021xalg = 1 and key_installed = false\n", __func__);
+                       }
+                       else
+                       {
+                               DBG_8192C("free psta =%p, aid =%d\n", psta, psta->aid);
+                               list_del_init(&psta->asoc_list);
+                               pstapriv->asoc_list_cnt--;
+                               updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
+                               psta = NULL;
+                               break;
+                       }
+               }
+       }
+       spin_unlock_bh(&pstapriv->asoc_list_lock);
+       associated_clients_update(padapter, updated);
+       DBG_871X("-"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
+       return ret;
+ }
+ static int cfg80211_rtw_change_station(struct wiphy *wiphy, struct net_device *ndev,
+                                 const u8 *mac, struct station_parameters *params)
+ {
+       DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
+       return 0;
+ }
+ static struct sta_info *rtw_sta_info_get_by_idx(const int idx, struct sta_priv *pstapriv)
+ {
+       struct list_head        *phead, *plist;
+       struct sta_info *psta = NULL;
+       int i = 0;
+       phead = &pstapriv->asoc_list;
+       plist = get_next(phead);
+       /* check asoc_queue */
+       while (phead != plist)
+       {
+               if (idx == i) psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
+               plist = get_next(plist);
+               i++;
+       }
+       return psta;
+ }
+ static int    cfg80211_rtw_dump_station(struct wiphy *wiphy, struct net_device *ndev,
+                              int idx, u8 *mac, struct station_info *sinfo)
+ {
+       int ret = 0;
+       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
+       struct sta_info *psta = NULL;
+       struct sta_priv *pstapriv = &padapter->stapriv;
+       DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
+       spin_lock_bh(&pstapriv->asoc_list_lock);
+       psta = rtw_sta_info_get_by_idx(idx, pstapriv);
+       spin_unlock_bh(&pstapriv->asoc_list_lock);
+       if (NULL == psta)
+       {
+               DBG_871X("Station is not found\n");
+               ret = -ENOENT;
+               goto exit;
+       }
+       memcpy(mac, psta->hwaddr, ETH_ALEN);
+       sinfo->filled = BIT(NL80211_STA_INFO_SIGNAL);
+       sinfo->signal = psta->rssi;
+ exit:
+       return ret;
+ }
+ static int    cfg80211_rtw_change_bss(struct wiphy *wiphy, struct net_device *ndev,
+                             struct bss_parameters *params)
+ {
+       DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
+       return 0;
+ }
+ void rtw_cfg80211_rx_action(struct adapter *adapter, u8 *frame, uint frame_len, const char*msg)
+ {
+       s32 freq;
+       int channel;
+       u8 category, action;
+       channel = rtw_get_oper_ch(adapter);
+       rtw_action_frame_parse(frame, frame_len, &category, &action);
+       DBG_8192C("RTW_Rx:cur_ch =%d\n", channel);
+       if (msg)
+               DBG_871X("RTW_Rx:%s\n", msg);
+       else
+               DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action);
+       freq = rtw_ieee80211_channel_to_frequency(channel, NL80211_BAND_2GHZ);
+       rtw_cfg80211_rx_mgmt(adapter, freq, 0, frame, frame_len, GFP_ATOMIC);
+ }
+ static int _cfg80211_rtw_mgmt_tx(struct adapter *padapter, u8 tx_ch, const u8 *buf, size_t len)
+ {
+       struct xmit_frame       *pmgntframe;
+       struct pkt_attrib       *pattrib;
+       unsigned char *pframe;
+       int ret = _FAIL;
+       bool ack = true;
+       struct ieee80211_hdr *pwlanhdr;
+       struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
+       struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+       rtw_set_scan_deny(padapter, 1000);
+       rtw_scan_abort(padapter);
+       if (tx_ch != rtw_get_oper_ch(padapter)) {
+               if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED))
+                       pmlmeext->cur_channel = tx_ch;
+               set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
+       }
+       /* starting alloc mgmt frame to dump it */
+       if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
+       {
+               /* ret = -ENOMEM; */
+               ret = _FAIL;
+               goto exit;
+       }
+       /* update attribute */
+       pattrib = &pmgntframe->attrib;
+       update_mgntframe_attrib(padapter, pattrib);
+       pattrib->retry_ctrl = false;
+       memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
+       pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
+       memcpy(pframe, (void*)buf, len);
+       pattrib->pktlen = len;
+       pwlanhdr = (struct ieee80211_hdr *)pframe;
+       /* update seq number */
+       pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
+       pattrib->seqnum = pmlmeext->mgnt_seq;
+       pmlmeext->mgnt_seq++;
+       pattrib->last_txcmdsz = pattrib->pktlen;
+       if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS)
+       {
+               ack = false;
+               ret = _FAIL;
+               #ifdef DEBUG_CFG80211
+               DBG_8192C("%s, ack == _FAIL\n", __func__);
+               #endif
+       }
+       else
+       {
+               msleep(50);
+               #ifdef DEBUG_CFG80211
+               DBG_8192C("%s, ack =%d, ok!\n", __func__, ack);
+               #endif
+               ret = _SUCCESS;
+       }
+ exit:
+       #ifdef DEBUG_CFG80211
+       DBG_8192C("%s, ret =%d\n", __func__, ret);
+       #endif
+       return ret;
+ }
+ static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy,
+       struct wireless_dev *wdev,
+       struct cfg80211_mgmt_tx_params *params,
+       u64 *cookie)
+ {
+       struct net_device *ndev = wdev_to_ndev(wdev);
+       struct ieee80211_channel *chan = params->chan;
+       const u8 *buf = params->buf;
+       size_t len = params->len;
+       int ret = 0;
+       int tx_ret;
+       u32 dump_limit = RTW_MAX_MGMT_TX_CNT;
+       u32 dump_cnt = 0;
+       bool ack = true;
+       u8 tx_ch = (u8)ieee80211_frequency_to_channel(chan->center_freq);
+       u8 category, action;
+       int type = (-1);
+       struct adapter *padapter;
+       struct rtw_wdev_priv *pwdev_priv;
+       if (ndev == NULL) {
+               ret = -EINVAL;
+               goto exit;
+       }
+       padapter = (struct adapter *)rtw_netdev_priv(ndev);
+       pwdev_priv = adapter_wdev_data(padapter);
+       /* cookie generation */
+       *cookie = (unsigned long) buf;
+ #ifdef DEBUG_CFG80211
+       DBG_871X(FUNC_ADPT_FMT" len =%zu, ch =%d"
+               "\n", FUNC_ADPT_ARG(padapter),
+               len, tx_ch
+       );
+ #endif /* DEBUG_CFG80211 */
+       /* indicate ack before issue frame to avoid racing with rsp frame */
+       rtw_cfg80211_mgmt_tx_status(padapter, *cookie, buf, len, ack, GFP_KERNEL);
+       if (rtw_action_frame_parse(buf, len, &category, &action) == false) {
+               DBG_8192C(FUNC_ADPT_FMT" frame_control:0x%x\n", FUNC_ADPT_ARG(padapter),
+                       le16_to_cpu(((struct ieee80211_hdr_3addr *)buf)->frame_control));
+               goto exit;
+       }
+       DBG_8192C("RTW_Tx:tx_ch =%d, da ="MAC_FMT"\n", tx_ch, MAC_ARG(GetAddr1Ptr(buf)));
+       if (category == RTW_WLAN_CATEGORY_PUBLIC)
+               DBG_871X("RTW_Tx:%s\n", action_public_str(action));
+       else
+               DBG_871X("RTW_Tx:category(%u), action(%u)\n", category, action);
+       rtw_ps_deny(padapter, PS_DENY_MGNT_TX);
+       if (_FAIL == rtw_pwr_wakeup(padapter)) {
+               ret = -EFAULT;
+               goto cancel_ps_deny;
+       }
+       do {
+               dump_cnt++;
+               tx_ret = _cfg80211_rtw_mgmt_tx(padapter, tx_ch, buf, len);
+       } while (dump_cnt < dump_limit && tx_ret != _SUCCESS);
+       if (tx_ret != _SUCCESS || dump_cnt > 1) {
+               DBG_871X(FUNC_ADPT_FMT" %s (%d/%d)\n", FUNC_ADPT_ARG(padapter),
+                       tx_ret == _SUCCESS?"OK":"FAIL", dump_cnt, dump_limit);
+       }
+       switch (type) {
+       case P2P_GO_NEGO_CONF:
+               rtw_clear_scan_deny(padapter);
+               break;
+       case P2P_INVIT_RESP:
+               if (pwdev_priv->invit_info.flags & BIT(0)
+                       && pwdev_priv->invit_info.status == 0)
+               {
+                       DBG_871X(FUNC_ADPT_FMT" agree with invitation of persistent group\n",
+                               FUNC_ADPT_ARG(padapter));
+                       rtw_set_scan_deny(padapter, 5000);
+                       rtw_pwr_wakeup_ex(padapter, 5000);
+                       rtw_clear_scan_deny(padapter);
+               }
+               break;
+       }
+ cancel_ps_deny:
+       rtw_ps_deny_cancel(padapter, PS_DENY_MGNT_TX);
+ exit:
+       return ret;
+ }
+ static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy,
+       struct wireless_dev *wdev,
+       u16 frame_type, bool reg)
+ {
+       struct net_device *ndev = wdev_to_ndev(wdev);
+       struct adapter *adapter;
+       if (ndev == NULL)
+               goto exit;
+       adapter = (struct adapter *)rtw_netdev_priv(ndev);
+ #ifdef DEBUG_CFG80211
+       DBG_871X(FUNC_ADPT_FMT" frame_type:%x, reg:%d\n", FUNC_ADPT_ARG(adapter),
+               frame_type, reg);
+ #endif
+       if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
+               return;
+ exit:
+       return;
+ }
+ #if defined(CONFIG_PNO_SUPPORT)
+ static int cfg80211_rtw_sched_scan_start(struct wiphy *wiphy,
+               struct net_device *dev,
+               struct cfg80211_sched_scan_request *request) {
+       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+       struct  mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+       u8 ret;
+       if (padapter->bup == false) {
+               DBG_871X("%s: net device is down.\n", __func__);
+               return -EIO;
+       }
+       if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true ||
+               check_fwstate(pmlmepriv, _FW_LINKED) == true  ||
+               check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) {
+               DBG_871X("%s: device is busy.\n", __func__);
+               rtw_scan_abort(padapter);
+       }
+       if (request == NULL) {
+               DBG_871X("%s: invalid cfg80211_requests parameters.\n", __func__);
+               return -EINVAL;
+       }
+       ret = rtw_android_cfg80211_pno_setup(dev, request->ssids,
+                       request->n_ssids, request->interval);
+       if (ret < 0) {
+               DBG_871X("%s ret: %d\n", __func__, ret);
+               goto exit;
+       }
+       ret = rtw_android_pno_enable(dev, true);
+       if (ret < 0) {
+               DBG_871X("%s ret: %d\n", __func__, ret);
+               goto exit;
+       }
+ exit:
+       return ret;
+ }
+ static int cfg80211_rtw_sched_scan_stop(struct wiphy *wiphy,
+               struct net_device *dev) {
+       return rtw_android_pno_enable(dev, false);
+ }
+ #endif /* CONFIG_PNO_SUPPORT */
+ static void rtw_cfg80211_init_ht_capab(struct ieee80211_sta_ht_cap *ht_cap, enum nl80211_band band, u8 rf_type)
+ {
+ #define MAX_BIT_RATE_40MHZ_MCS15      300     /* Mbps */
+ #define MAX_BIT_RATE_40MHZ_MCS7               150     /* Mbps */
+       ht_cap->ht_supported = true;
+       ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
+                                       IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20 |
+                                       IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU;
+       /*
+        *Maximum length of AMPDU that the STA can receive.
+        *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
+        */
+       ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
+       /*Minimum MPDU start spacing , */
+       ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
+       ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
+       /*
+        *hw->wiphy->bands[NL80211_BAND_2GHZ]
+        *base on ant_num
+        *rx_mask: RX mask
+        *if rx_ant = 1 rx_mask[0]= 0xff;==>MCS0-MCS7
+        *if rx_ant =2 rx_mask[1]= 0xff;==>MCS8-MCS15
+        *if rx_ant >=3 rx_mask[2]= 0xff;
+        *if BW_40 rx_mask[4]= 0x01;
+        *highest supported RX rate
+        */
+       if (rf_type == RF_1T1R)
+       {
+               ht_cap->mcs.rx_mask[0] = 0xFF;
+               ht_cap->mcs.rx_mask[1] = 0x00;
+               ht_cap->mcs.rx_mask[4] = 0x01;
+               ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS7);
+       }
+       else if ((rf_type == RF_1T2R) || (rf_type ==RF_2T2R))
+       {
+               ht_cap->mcs.rx_mask[0] = 0xFF;
+               ht_cap->mcs.rx_mask[1] = 0xFF;
+               ht_cap->mcs.rx_mask[4] = 0x01;
+               ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS15);
+       }
+       else
+       {
+               DBG_8192C("%s, error rf_type =%d\n", __func__, rf_type);
+       }
+ }
+ void rtw_cfg80211_init_wiphy(struct adapter *padapter)
+ {
+       u8 rf_type;
+       struct ieee80211_supported_band *bands;
+       struct wireless_dev *pwdev = padapter->rtw_wdev;
+       struct wiphy *wiphy = pwdev->wiphy;
+       rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
+       DBG_8192C("%s:rf_type =%d\n", __func__, rf_type);
+       {
+               bands = wiphy->bands[NL80211_BAND_2GHZ];
+               if (bands)
+                       rtw_cfg80211_init_ht_capab(&bands->ht_cap, NL80211_BAND_2GHZ, rf_type);
+       }
+       /* init regulary domain */
+       rtw_regd_init(padapter, rtw_reg_notifier);
+       /* copy mac_addr to wiphy */
+       memcpy(wiphy->perm_addr, padapter->eeprompriv.mac_addr, ETH_ALEN);
+ }
+ static void rtw_cfg80211_preinit_wiphy(struct adapter *padapter, struct wiphy *wiphy)
+ {
+       wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+       wiphy->max_scan_ssids = RTW_SSID_SCAN_AMOUNT;
+       wiphy->max_scan_ie_len = RTW_SCAN_IE_LEN_MAX;
+       wiphy->max_num_pmkids = RTW_MAX_NUM_PMKIDS;
+       wiphy->max_remain_on_channel_duration = RTW_MAX_REMAIN_ON_CHANNEL_DURATION;
+       wiphy->interface_modes =        BIT(NL80211_IFTYPE_STATION)
+                                                               | BIT(NL80211_IFTYPE_ADHOC)
+                                                               | BIT(NL80211_IFTYPE_AP)
+                                                               | BIT(NL80211_IFTYPE_MONITOR)
+                                                               ;
+       wiphy->mgmt_stypes = rtw_cfg80211_default_mgmt_stypes;
+       wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR);
+       wiphy->cipher_suites = rtw_cipher_suites;
+       wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites);
+       /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
+       wiphy->bands[NL80211_BAND_2GHZ] = rtw_spt_band_alloc(NL80211_BAND_2GHZ);
+       wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
+       wiphy->flags |= WIPHY_FLAG_OFFCHAN_TX | WIPHY_FLAG_HAVE_AP_SME;
+ #if defined(CONFIG_PM)
++      wiphy->max_sched_scan_reqs = 1;
+ #ifdef CONFIG_PNO_SUPPORT
+       wiphy->max_sched_scan_ssids = MAX_PNO_LIST_COUNT;
+ #endif
+ #endif
+ #if defined(CONFIG_PM)
+       wiphy->wowlan = &wowlan_stub;
+ #endif
+       if (padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
+               wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
+       else
+               wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
+ }
+ static struct cfg80211_ops rtw_cfg80211_ops = {
+       .change_virtual_intf = cfg80211_rtw_change_iface,
+       .add_key = cfg80211_rtw_add_key,
+       .get_key = cfg80211_rtw_get_key,
+       .del_key = cfg80211_rtw_del_key,
+       .set_default_key = cfg80211_rtw_set_default_key,
+       .get_station = cfg80211_rtw_get_station,
+       .scan = cfg80211_rtw_scan,
+       .set_wiphy_params = cfg80211_rtw_set_wiphy_params,
+       .connect = cfg80211_rtw_connect,
+       .disconnect = cfg80211_rtw_disconnect,
+       .join_ibss = cfg80211_rtw_join_ibss,
+       .leave_ibss = cfg80211_rtw_leave_ibss,
+       .set_tx_power = cfg80211_rtw_set_txpower,
+       .get_tx_power = cfg80211_rtw_get_txpower,
+       .set_power_mgmt = cfg80211_rtw_set_power_mgmt,
+       .set_pmksa = cfg80211_rtw_set_pmksa,
+       .del_pmksa = cfg80211_rtw_del_pmksa,
+       .flush_pmksa = cfg80211_rtw_flush_pmksa,
+       .add_virtual_intf = cfg80211_rtw_add_virtual_intf,
+       .del_virtual_intf = cfg80211_rtw_del_virtual_intf,
+       .start_ap = cfg80211_rtw_start_ap,
+       .change_beacon = cfg80211_rtw_change_beacon,
+       .stop_ap = cfg80211_rtw_stop_ap,
+       .add_station = cfg80211_rtw_add_station,
+       .del_station = cfg80211_rtw_del_station,
+       .change_station = cfg80211_rtw_change_station,
+       .dump_station = cfg80211_rtw_dump_station,
+       .change_bss = cfg80211_rtw_change_bss,
+       .mgmt_tx = cfg80211_rtw_mgmt_tx,
+       .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register,
+ #if defined(CONFIG_PNO_SUPPORT)
+       .sched_scan_start = cfg80211_rtw_sched_scan_start,
+       .sched_scan_stop = cfg80211_rtw_sched_scan_stop,
+ #endif /* CONFIG_PNO_SUPPORT */
+ };
+ int rtw_wdev_alloc(struct adapter *padapter, struct device *dev)
+ {
+       int ret = 0;
+       struct wiphy *wiphy;
+       struct wireless_dev *wdev;
+       struct rtw_wdev_priv *pwdev_priv;
+       struct net_device *pnetdev = padapter->pnetdev;
+       DBG_8192C("%s(padapter =%p)\n", __func__, padapter);
+       /* wiphy */
+       wiphy = wiphy_new(&rtw_cfg80211_ops, sizeof(struct adapter *));
+       if (!wiphy) {
+               DBG_8192C("Couldn't allocate wiphy device\n");
+               ret = -ENOMEM;
+               goto exit;
+       }
+       set_wiphy_dev(wiphy, dev);
+       *((struct adapter **)wiphy_priv(wiphy)) = padapter;
+       rtw_cfg80211_preinit_wiphy(padapter, wiphy);
+       ret = wiphy_register(wiphy);
+       if (ret < 0) {
+               DBG_8192C("Couldn't register wiphy device\n");
+               goto free_wiphy;
+       }
+       /*  wdev */
+       wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev));
+       if (!wdev) {
+               DBG_8192C("Couldn't allocate wireless device\n");
+               ret = -ENOMEM;
+               goto unregister_wiphy;
+       }
+       wdev->wiphy = wiphy;
+       wdev->netdev = pnetdev;
+       wdev->iftype = NL80211_IFTYPE_STATION; /*  will be init in rtw_hal_init() */
+                                              /*  Must sync with _rtw_init_mlme_priv() */
+                                          /*  pmlmepriv->fw_state = WIFI_STATION_STATE */
+       padapter->rtw_wdev = wdev;
+       pnetdev->ieee80211_ptr = wdev;
+       /* init pwdev_priv */
+       pwdev_priv = adapter_wdev_data(padapter);
+       pwdev_priv->rtw_wdev = wdev;
+       pwdev_priv->pmon_ndev = NULL;
+       pwdev_priv->ifname_mon[0] = '\0';
+       pwdev_priv->padapter = padapter;
+       pwdev_priv->scan_request = NULL;
+       spin_lock_init(&pwdev_priv->scan_req_lock);
+       pwdev_priv->p2p_enabled = false;
+       pwdev_priv->provdisc_req_issued = false;
+       rtw_wdev_invit_info_init(&pwdev_priv->invit_info);
+       rtw_wdev_nego_info_init(&pwdev_priv->nego_info);
+       pwdev_priv->bandroid_scan = false;
+       if (padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
+               pwdev_priv->power_mgmt = true;
+       else
+               pwdev_priv->power_mgmt = false;
+       kfree((u8 *)wdev);
+       return ret;
+ unregister_wiphy:
+       wiphy_unregister(wiphy);
+  free_wiphy:
+       wiphy_free(wiphy);
+ exit:
+       return ret;
+ }
+ void rtw_wdev_free(struct wireless_dev *wdev)
+ {
+       DBG_8192C("%s(wdev =%p)\n", __func__, wdev);
+       if (!wdev)
+               return;
+       rtw_spt_band_free(wdev->wiphy->bands[NL80211_BAND_2GHZ]);
+       wiphy_free(wdev->wiphy);
+       kfree((u8 *)wdev);
+ }
+ void rtw_wdev_unregister(struct wireless_dev *wdev)
+ {
+       struct net_device *ndev;
+       struct adapter *adapter;
+       struct rtw_wdev_priv *pwdev_priv;
+       DBG_8192C("%s(wdev =%p)\n", __func__, wdev);
+       if (!wdev)
+               return;
+       if (!(ndev = wdev_to_ndev(wdev)))
+               return;
+       adapter = (struct adapter *)rtw_netdev_priv(ndev);
+       pwdev_priv = adapter_wdev_data(adapter);
+       rtw_cfg80211_indicate_scan_done(adapter, true);
+       if (pwdev_priv->pmon_ndev) {
+               DBG_8192C("%s, unregister monitor interface\n", __func__);
+               unregister_netdev(pwdev_priv->pmon_ndev);
+       }
+       wiphy_unregister(wdev->wiphy);
+ }
index 2b4536318ca62b6bb464c2c16dcde34b6540e0c0,b02a83bac1665d9443316a90b8a03a2110f07837..44a12bdd6a46d25bc2c90cdbaaf7223c8daefe38
@@@ -29,8 -29,8 +29,8 @@@
  #define P2P_INV_REQ                   0x03
  #define P2P_INV_RSP                   0x04
  #define PUBLIC_ACT_VENDORSPEC         0x09
- #define GAS_INTIAL_REQ                        0x0a
- #define GAS_INTIAL_RSP                        0x0b
+ #define GAS_INITIAL_REQ                       0x0a
+ #define GAS_INITIAL_RSP                       0x0b
  
  #define INVALID_CHANNEL                       0
  
@@@ -205,11 -205,11 +205,11 @@@ static u32 get_rssi_avg(struct network_
  {
        u8 i;
        int rssi_v = 0;
-       u8 num_rssi = (network_info->str_rssi.u8Full) ?
-                      NUM_RSSI : (network_info->str_rssi.u8Index);
+       u8 num_rssi = (network_info->rssi_history.full) ?
+                      NUM_RSSI : (network_info->rssi_history.index);
  
        for (i = 0; i < num_rssi; i++)
-               rssi_v += network_info->str_rssi.as8RSSI[i];
+               rssi_v += network_info->rssi_history.samples[i];
  
        rssi_v /= num_rssi;
        return rssi_v;
@@@ -346,13 -346,13 +346,13 @@@ static void add_network_to_shadow(struc
        } else {
                ap_index = ap_found;
        }
-       rssi_index = last_scanned_shadow[ap_index].str_rssi.u8Index;
-       last_scanned_shadow[ap_index].str_rssi.as8RSSI[rssi_index++] = pstrNetworkInfo->rssi;
+       rssi_index = last_scanned_shadow[ap_index].rssi_history.index;
+       last_scanned_shadow[ap_index].rssi_history.samples[rssi_index++] = pstrNetworkInfo->rssi;
        if (rssi_index == NUM_RSSI) {
                rssi_index = 0;
-               last_scanned_shadow[ap_index].str_rssi.u8Full = 1;
+               last_scanned_shadow[ap_index].rssi_history.full = true;
        }
-       last_scanned_shadow[ap_index].str_rssi.u8Index = rssi_index;
+       last_scanned_shadow[ap_index].rssi_history.index = rssi_index;
        last_scanned_shadow[ap_index].rssi = pstrNetworkInfo->rssi;
        last_scanned_shadow[ap_index].cap_info = pstrNetworkInfo->cap_info;
        last_scanned_shadow[ap_index].ssid_len = pstrNetworkInfo->ssid_len;
@@@ -765,8 -765,8 +765,8 @@@ static int connect(struct wiphy *wiphy
                }
        }
  
-       if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
-           || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
+       if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) ||
+           (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
                for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
                        if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP)
                                u8security = u8security | TKIP;
@@@ -1301,16 -1301,16 +1301,16 @@@ static int set_pmksa(struct wiphy *wiph
  
        for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
                if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
-                                ETH_ALEN)) {
+                           ETH_ALEN)) {
                        flag = PMKID_FOUND;
                        break;
                }
        }
        if (i < WILC_MAX_NUM_PMKIDS) {
                memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
-                           ETH_ALEN);
+                      ETH_ALEN);
                memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
-                           PMKID_LEN);
+                      PMKID_LEN);
                if (!(flag == PMKID_FOUND))
                        priv->pmkid_list.numpmkid++;
        } else {
@@@ -1334,7 -1334,7 +1334,7 @@@ static int del_pmksa(struct wiphy *wiph
  
        for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
                if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
-                                ETH_ALEN)) {
+                           ETH_ALEN)) {
                        memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
                        break;
                }
        if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
                for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
                        memcpy(priv->pmkid_list.pmkidlist[i].bssid,
-                                   priv->pmkid_list.pmkidlist[i + 1].bssid,
-                                   ETH_ALEN);
+                              priv->pmkid_list.pmkidlist[i + 1].bssid,
+                              ETH_ALEN);
                        memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
-                                   priv->pmkid_list.pmkidlist[i].pmkid,
-                                   PMKID_LEN);
+                              priv->pmkid_list.pmkidlist[i + 1].pmkid,
+                              PMKID_LEN);
                }
                priv->pmkid_list.numpmkid--;
        } else {
@@@ -1477,10 -1477,10 +1477,10 @@@ void WILC_WFI_p2p_rx(struct net_device 
                        }
                        if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
                                switch (buff[ACTION_SUBTYPE_ID]) {
-                               case GAS_INTIAL_REQ:
+                               case GAS_INITIAL_REQ:
                                        break;
  
-                               case GAS_INTIAL_RSP:
+                               case GAS_INITIAL_RSP:
                                        break;
  
                                case PUBLIC_ACT_VENDORSPEC:
                                                        }
                                                }
                                                if (p2p_local_random > p2p_recv_random) {
-                                                       if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
-                                                             || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
+                                                       if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP ||
+                                                            buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
                                                                for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
                                                                        if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) {
                                                                                WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
@@@ -1666,10 -1666,10 +1666,10 @@@ static int mgmt_tx(struct wiphy *wiphy
                                        curr_channel = chan->hw_value;
                                }
                                switch (buf[ACTION_SUBTYPE_ID]) {
-                               case GAS_INTIAL_REQ:
+                               case GAS_INITIAL_REQ:
                                        break;
  
-                               case GAS_INTIAL_RSP:
+                               case GAS_INITIAL_RSP:
                                        break;
  
                                case PUBLIC_ACT_VENDORSPEC:
                                                        }
                                                }
  
-                                               if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
-                                                     || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
+                                               if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP ||
+                                                    buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
                                                        if (p2p_local_random > p2p_recv_random) {
                                                                for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
                                                                        if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) {
@@@ -1837,7 -1837,7 +1837,7 @@@ static int set_power_mgmt(struct wiphy 
  }
  
  static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
 -                             enum nl80211_iftype type, u32 *flags, struct vif_params *params)
 +                             enum nl80211_iftype type, struct vif_params *params)
  {
        struct wilc_priv *priv;
        struct wilc_vif *vif;
@@@ -2099,6 -2099,7 +2099,6 @@@ static struct wireless_dev *add_virtual
                                             const char *name,
                                             unsigned char name_assign_type,
                                             enum nl80211_iftype type,
 -                                           u32 *flags,
                                             struct vif_params *params)
  {
        struct wilc_vif *vif;
diff --combined include/linux/sched.h
index 993e7e25a3a55c283b9fe1bc3b4a2a6796574954,942c2250301b46a7f601dc07d6ddeabdfd7d7e13..2b69fc65020131bed57e41d4b228ed0c59692a5c
@@@ -186,7 -186,7 +186,7 @@@ extern long io_schedule_timeout(long ti
  extern void io_schedule(void);
  
  /**
 - * struct prev_cputime - snaphsot of system and user cputime
 + * struct prev_cputime - snapshot of system and user cputime
   * @utime: time spent in user mode
   * @stime: time spent in system mode
   * @lock: protects the above two fields
@@@ -604,10 -604,6 +604,10 @@@ struct task_struct 
  #ifdef CONFIG_COMPAT_BRK
        unsigned                        brk_randomized:1;
  #endif
 +#ifdef CONFIG_CGROUPS
 +      /* disallow userland-initiated cgroup migration */
 +      unsigned                        no_cgroup_migration:1;
 +#endif
  
        unsigned long                   atomic_flags; /* Flags requiring atomic access. */
  
        /* PI waiters blocked on a rt_mutex held by this task: */
        struct rb_root                  pi_waiters;
        struct rb_node                  *pi_waiters_leftmost;
 +      /* Updated under owner's pi_lock and rq lock */
 +      struct task_struct              *pi_top_task;
        /* Deadlock detection and priority inheritance handling: */
        struct rt_mutex_waiter          *pi_blocked_on;
  #endif
  #ifdef CONFIG_THREAD_INFO_IN_TASK
        /* A live task holds one reference: */
        atomic_t                        stack_refcount;
 +#endif
 +#ifdef CONFIG_LIVEPATCH
 +      int patch_state;
 +#endif
 +#ifdef CONFIG_SECURITY
 +      /* Used by LSM modules for access restriction: */
 +      void                            *security;
  #endif
        /* CPU-specific state of this task: */
        struct thread_struct            thread;
@@@ -1224,9 -1211,9 +1224,9 @@@ extern struct pid *cad_pid
  #define PF_USED_ASYNC         0x00004000      /* Used async_schedule*(), used by module init */
  #define PF_NOFREEZE           0x00008000      /* This thread should not be frozen */
  #define PF_FROZEN             0x00010000      /* Frozen for system suspend */
 -#define PF_FSTRANS            0x00020000      /* Inside a filesystem transaction */
 -#define PF_KSWAPD             0x00040000      /* I am kswapd */
 -#define PF_MEMALLOC_NOIO      0x00080000      /* Allocating memory without IO involved */
 +#define PF_KSWAPD             0x00020000      /* I am kswapd */
 +#define PF_MEMALLOC_NOFS      0x00040000      /* All allocation requests will inherit GFP_NOFS */
 +#define PF_MEMALLOC_NOIO      0x00080000      /* All allocation requests will inherit GFP_NOIO */
  #define PF_LESS_THROTTLE      0x00100000      /* Throttle me less: I clean memory */
  #define PF_KTHREAD            0x00200000      /* I am a kernel thread */
  #define PF_RANDOMIZE          0x00400000      /* Randomize virtual address space */
  #define PFA_NO_NEW_PRIVS              0       /* May not gain new privileges. */
  #define PFA_SPREAD_PAGE                       1       /* Spread page cache over cpuset */
  #define PFA_SPREAD_SLAB                       2       /* Spread some slab caches over cpuset */
- #define PFA_LMK_WAITING                       3       /* Lowmemorykiller is waiting */
  
  
  #define TASK_PFA_TEST(name, func)                                     \
@@@ -1295,14 -1281,11 +1294,11 @@@ TASK_PFA_TEST(SPREAD_SLAB, spread_slab
  TASK_PFA_SET(SPREAD_SLAB, spread_slab)
  TASK_PFA_CLEAR(SPREAD_SLAB, spread_slab)
  
- TASK_PFA_TEST(LMK_WAITING, lmk_waiting)
- TASK_PFA_SET(LMK_WAITING, lmk_waiting)
  static inline void
 -tsk_restore_flags(struct task_struct *task, unsigned long orig_flags, unsigned long flags)
 +current_restore_flags(unsigned long orig_flags, unsigned long flags)
  {
 -      task->flags &= ~flags;
 -      task->flags |= orig_flags & flags;
 +      current->flags &= ~flags;
 +      current->flags |= orig_flags & flags;
  }
  
  extern int cpuset_cpumask_can_shrink(const struct cpumask *cur, const struct cpumask *trial);
This page took 0.353942 seconds and 4 git commands to generate.