aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/kernel-parameters.txt15
-rw-r--r--Documentation/printk-formats.txt5
-rw-r--r--Documentation/sysctl/kernel.txt9
-rw-r--r--MAINTAINERS10
-rw-r--r--Makefile10
-rw-r--r--android/configs/android-base.cfg2
-rw-r--r--arch/arm/boot/dts/qcom/msm8952-gpu.dtsi2
-rw-r--r--arch/arm/common/Kconfig46
-rw-r--r--arch/arm/common/Makefile1
-rw-r--r--arch/arm/common/fiq_debugger.c1376
-rw-r--r--arch/arm/common/fiq_debugger_ringbuf.h94
-rw-r--r--arch/arm/configs/athene_defconfig32
-rw-r--r--arch/arm/include/asm/fiq_debugger.h64
-rw-r--r--arch/arm/include/asm/pgalloc.h10
-rw-r--r--arch/arm/include/asm/pgtable-2level-hwdef.h2
-rw-r--r--arch/arm/include/asm/pgtable-3level-hwdef.h1
-rw-r--r--arch/arm/mach-sa1100/generic.c2
-rw-r--r--arch/arm/mm/mmu.c26
-rw-r--r--arch/arm64/Kconfig15
-rw-r--r--arch/arm64/include/uapi/asm/ptrace.h1
-rw-r--r--arch/arm64/kernel/entry.S2
-rw-r--r--arch/arm64/kernel/fpsimd.c1
-rw-r--r--arch/arm64/kernel/ptrace.c24
-rw-r--r--arch/arm64/kernel/setup.c6
-rw-r--r--arch/arm64/kernel/traps.c25
-rw-r--r--arch/arm64/kernel/vdso/vdso.S3
-rw-r--r--arch/mips/include/asm/branch.h5
-rw-r--r--arch/mips/include/uapi/asm/unistd.h30
-rw-r--r--arch/mips/kernel/branch.c8
-rw-r--r--arch/mips/kernel/scall32-o32.S6
-rw-r--r--arch/mips/kernel/scall64-64.S4
-rw-r--r--arch/mips/kernel/scall64-n32.S4
-rw-r--r--arch/mips/kernel/scall64-o32.S6
-rw-r--r--arch/mips/kernel/syscall.c2
-rw-r--r--arch/mips/math-emu/cp1emu.c38
-rw-r--r--arch/powerpc/include/asm/atomic.h4
-rw-r--r--arch/powerpc/include/asm/reg.h2
-rw-r--r--arch/powerpc/kernel/kprobes.c11
-rw-r--r--arch/powerpc/lib/sstep.c13
-rw-r--r--arch/x86/include/asm/io.h4
-rw-r--r--arch/x86/kernel/apic/apic.c2
-rw-r--r--arch/x86/kernel/kvm.c2
-rw-r--r--arch/x86/kvm/vmx.c2
-rw-r--r--arch/x86/kvm/x86.c2
-rw-r--r--arch/x86/mm/numa_32.c1
-rw-r--r--block/bfq-iosched.c8
-rw-r--r--block/bfq-sched.c3
-rw-r--r--block/blk-ioc.c3
-rw-r--r--block/genhd.c12
-rw-r--r--crypto/algif_skcipher.c4
-rw-r--r--crypto/blkcipher.c3
-rw-r--r--drivers/acpi/apei/ghes.c1
-rw-r--r--drivers/acpi/sysfs.c7
-rw-r--r--drivers/android/binder.c2
-rw-r--r--drivers/ata/libata-scsi.c6
-rw-r--r--drivers/base/core.c3
-rw-r--r--drivers/base/firmware_class.c7
-rw-r--r--drivers/base/power/domain.c4
-rw-r--r--drivers/base/power/main.c1
-rw-r--r--drivers/base/power/wakeup.c153
-rw-r--r--drivers/char/Kconfig4
-rw-r--r--drivers/char/Makefile1
-rw-r--r--drivers/char/dcc_tty.c326
-rw-r--r--drivers/char/diag/diagchar_core.c2
-rw-r--r--drivers/cpufreq/cpufreq.c10
-rw-r--r--drivers/cpufreq/cpufreq_conservative.c4
-rw-r--r--drivers/cpufreq/cpufreq_governor.c25
-rw-r--r--drivers/cpufreq/cpufreq_governor.h9
-rw-r--r--drivers/cpufreq/cpufreq_interactive.c3
-rw-r--r--drivers/cpufreq/cpufreq_stats.c2
-rw-r--r--drivers/cpufreq/freq_table.c12
-rw-r--r--drivers/cpufreq/qcom-cpufreq.c7
-rw-r--r--drivers/cpufreq/s3c2416-cpufreq.c1
-rw-r--r--drivers/crypto/caam/caamhash.c2
-rw-r--r--drivers/crypto/caam/key_gen.c2
-rw-r--r--drivers/crypto/msm/compat_qcedev.c10
-rw-r--r--drivers/crypto/msm/qce50.c5
-rw-r--r--drivers/crypto/msm/qcrypto.c14
-rw-r--r--drivers/crypto/talitos.c7
-rw-r--r--drivers/devfreq/Kconfig9
-rw-r--r--drivers/devfreq/Makefile1
-rw-r--r--drivers/devfreq/adreno_idler.c113
-rw-r--r--drivers/devfreq/devfreq.c28
-rw-r--r--drivers/devfreq/governor_gpubw_mon.c3
-rw-r--r--drivers/devfreq/governor_msm_adreno_tz.c196
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c2
-rw-r--r--drivers/gpu/msm/adreno_a4xx.c4
-rw-r--r--drivers/gpu/msm/kgsl_cmdbatch.c63
-rw-r--r--drivers/gpu/msm/kgsl_pwrctrl.c9
-rw-r--r--drivers/hid/usbhid/hiddev.c17
-rw-r--r--drivers/i2c/i2c-core.c2
-rw-r--r--drivers/infiniband/hw/qib/qib_iba7322.c2
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_vlan.c4
-rw-r--r--drivers/input/joystick/xpad.c3
-rw-r--r--drivers/input/touchscreen/Kconfig10
-rw-r--r--drivers/input/touchscreen/synaptics_fw_update.c68
-rw-r--r--drivers/iommu/amd_iommu.c1
-rw-r--r--drivers/md/bitmap.c5
-rw-r--r--drivers/md/dm-android-verity.c14
-rw-r--r--drivers/md/dm-android-verity.h12
-rw-r--r--drivers/md/dm-linear.c30
-rw-r--r--drivers/md/md.c2
-rw-r--r--drivers/md/raid10.c19
-rw-r--r--drivers/media/platform/davinci/vpfe_capture.c22
-rw-r--r--drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.c21
-rw-r--r--drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.h2
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c4
-rwxr-xr-x[-rw-r--r--]drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c8
-rw-r--r--drivers/media/platform/msm/camera_v2/msm.c94
-rw-r--r--drivers/media/platform/msm/camera_v2/msm.h7
-rw-r--r--drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c4
-rw-r--r--drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c121
-rw-r--r--drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.h3
-rwxr-xr-x[-rw-r--r--]drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c7
-rwxr-xr-xdrivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c25
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c6
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_debug.c2
-rw-r--r--drivers/media/rc/imon.c2
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-eeprom.c13
-rw-r--r--drivers/media/v4l2-core/v4l2-compat-ioctl32.c9
-rw-r--r--drivers/mfd/omap-usb-tll.c2
-rw-r--r--drivers/misc/Makefile3
-rw-r--r--drivers/misc/c2port/c2port-duramar2150.c4
-rw-r--r--drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c65
-rw-r--r--drivers/misc/qcom/qdsp6v2/audio_utils_aio.c2
-rw-r--r--drivers/misc/qseecom.c18
-rw-r--r--drivers/misc/uid_sys_stats.c305
-rw-r--r--drivers/mmc/card/block.c2
-rw-r--r--drivers/net/can/usb/esd_usb2.c2
-rw-r--r--drivers/net/ethernet/korina.c8
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/icm.c7
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c2
-rw-r--r--drivers/net/ethernet/msm/msm_rmnet_bam.c2
-rw-r--r--drivers/net/ethernet/msm/msm_rmnet_smux.c2
-rw-r--r--drivers/net/ethernet/qlogic/qlge/qlge_dbg.c2
-rw-r--r--drivers/net/ethernet/xilinx/xilinx_emaclite.c10
-rw-r--r--drivers/net/phy/marvell.c2
-rw-r--r--drivers/net/phy/phy.c9
-rw-r--r--drivers/net/team/team.c8
-rw-r--r--drivers/net/wireless/cnss/cnss_pci.c50
-rw-r--r--drivers/platform/msm/ipa/ipa.c2
-rw-r--r--drivers/platform/msm/ipa/ipa_flt.c18
-rw-r--r--drivers/platform/msm/ipa/ipa_hdr.c38
-rw-r--r--drivers/platform/msm/ipa/ipa_i.h18
-rw-r--r--drivers/platform/msm/ipa/ipa_rt.c36
-rw-r--r--drivers/platform/msm/ipa/rmnet_ipa.c10
-rw-r--r--drivers/platform/msm/mhi/mhi_sys.c28
-rw-r--r--drivers/platform/msm/msm_bus/msm_bus_dbg.c124
-rw-r--r--drivers/platform/msm/msm_bus/msm_bus_dbg_voter.c1
-rw-r--r--drivers/power/qcom/msm-core.c5
-rw-r--r--drivers/power/qpnp-fg.c22
-rw-r--r--drivers/regulator/core.c5
-rw-r--r--drivers/s390/scsi/zfcp_dbf.c21
-rw-r--r--drivers/s390/scsi/zfcp_dbf.h6
-rw-r--r--drivers/s390/scsi/zfcp_fc.h6
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c3
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c8
-rw-r--r--drivers/scsi/device_handler/scsi_dh_emc.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c8
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c8
-rw-r--r--drivers/soc/qcom/mpm-of.c2
-rw-r--r--drivers/soc/qcom/peripheral-loader.c4
-rw-r--r--drivers/soc/qcom/qdsp6v2/voice_svc.c26
-rw-r--r--drivers/soc/qcom/rpm-smd.c2
-rw-r--r--drivers/soc/qcom/smp2p_spinlock_test.c4
-rw-r--r--drivers/soc/qcom/socinfo.c40
-rw-r--r--drivers/soc/qcom/watchdog_v2.c122
-rw-r--r--drivers/staging/android/ion/ion.c14
-rw-r--r--drivers/staging/android/ion/ion_carveout_heap.c3
-rw-r--r--drivers/staging/android/ion/ion_priv.h7
-rw-r--r--drivers/staging/android/ion/ion_system_heap.c4
-rw-r--r--drivers/staging/android/ion/msm/msm_ion.c16
-rw-r--r--drivers/staging/android/oneshot_sync.c2
-rw-r--r--drivers/staging/comedi/comedi_fops.c7
-rw-r--r--drivers/staging/iio/resolver/ad2s1210.c2
-rw-r--r--drivers/staging/prima/Android.mk37
-rw-r--r--drivers/staging/prima/CORE/HDD/inc/qc_sap_ioctl.h13
-rw-r--r--drivers/staging/prima/CORE/HDD/inc/wlan_hdd_assoc.h95
-rw-r--r--drivers/staging/prima/CORE/HDD/inc/wlan_hdd_cfg.h267
-rw-r--r--drivers/staging/prima/CORE/HDD/inc/wlan_hdd_cfg80211.h156
-rw-r--r--drivers/staging/prima/CORE/HDD/inc/wlan_hdd_hostapd.h30
-rw-r--r--drivers/staging/prima/CORE/HDD/inc/wlan_hdd_main.h197
-rw-r--r--drivers/staging/prima/CORE/HDD/inc/wlan_hdd_oemdata.h3
-rw-r--r--drivers/staging/prima/CORE/HDD/inc/wlan_hdd_tdls.h2
-rw-r--r--drivers/staging/prima/CORE/HDD/inc/wlan_hdd_tx_rx.h12
-rw-r--r--drivers/staging/prima/CORE/HDD/inc/wlan_hdd_wext.h4
-rw-r--r--drivers/staging/prima/CORE/HDD/src/wlan_hdd_assoc.c589
-rw-r--r--drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg.c401
-rw-r--r--drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg80211.c1421
-rw-r--r--drivers/staging/prima/CORE/HDD/src/wlan_hdd_dev_pwr.c6
-rw-r--r--drivers/staging/prima/CORE/HDD/src/wlan_hdd_early_suspend.c233
-rw-r--r--drivers/staging/prima/CORE/HDD/src/wlan_hdd_hostapd.c451
-rw-r--r--drivers/staging/prima/CORE/HDD/src/wlan_hdd_main.c2170
-rw-r--r--drivers/staging/prima/CORE/HDD/src/wlan_hdd_oemdata.c17
-rw-r--r--drivers/staging/prima/CORE/HDD/src/wlan_hdd_p2p.c43
-rw-r--r--drivers/staging/prima/CORE/HDD/src/wlan_hdd_softap_tx_rx.c27
-rw-r--r--drivers/staging/prima/CORE/HDD/src/wlan_hdd_tdls.c38
-rw-r--r--drivers/staging/prima/CORE/HDD/src/wlan_hdd_tx_rx.c123
-rw-r--r--drivers/staging/prima/CORE/HDD/src/wlan_hdd_wext.c222
-rw-r--r--drivers/staging/prima/CORE/MAC/inc/aniGlobal.h33
-rw-r--r--drivers/staging/prima/CORE/MAC/inc/qwlan_version.h4
-rw-r--r--drivers/staging/prima/CORE/MAC/inc/sirApi.h282
-rw-r--r--drivers/staging/prima/CORE/MAC/inc/sirMacProtDef.h5
-rw-r--r--drivers/staging/prima/CORE/MAC/inc/wniApi.h12
-rw-r--r--drivers/staging/prima/CORE/MAC/inc/wniCfg.h27
-rw-r--r--drivers/staging/prima/CORE/MAC/src/cfg/cfgApi.c11
-rw-r--r--drivers/staging/prima/CORE/MAC/src/cfg/cfgProcMsg.c27
-rw-r--r--drivers/staging/prima/CORE/MAC/src/cfg/cfgUtil/dot11f.frms28
-rw-r--r--drivers/staging/prima/CORE/MAC/src/include/dot11f.h49
-rw-r--r--drivers/staging/prima/CORE/MAC/src/include/dphGlobal.h30
-rw-r--r--drivers/staging/prima/CORE/MAC/src/include/parserApi.h24
-rw-r--r--drivers/staging/prima/CORE/MAC/src/include/sirParams.h53
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/include/limApi.h5
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/include/limFT.h3
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/include/limFTDefs.h7
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/include/limSession.h18
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/include/lim_mbb.h48
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limApi.c180
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limAssocUtils.c72
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limAssocUtils.h3
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limFT.c8
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c23
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessActionFrame.c52
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessAssocReqFrame.c51
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c113
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessAuthFrame.c83
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c14
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessDisassocFrame.c13
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMessageQueue.c126
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c83
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c56
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessProbeReqFrame.c4
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c187
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limPropExtsUtils.c6
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limSecurityUtils.c40
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limSecurityUtils.h12
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limSendManagementFrames.c49
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c30
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limSerDesUtils.c95
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limSerDesUtils.h8
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limSession.c16
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limTimerUtils.c62
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limTimerUtils.h8
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limTrace.c6
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limTypes.h18
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limUtils.c636
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/limUtils.h10
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/lim/lim_mbb.c1754
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/pmm/pmmApi.c41
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/sch/schBeaconGen.c7
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/sch/schBeaconProcess.c9
-rw-r--r--drivers/staging/prima/CORE/SAP/inc/sapApi.h24
-rw-r--r--drivers/staging/prima/CORE/SAP/src/sapModule.c45
-rw-r--r--drivers/staging/prima/CORE/SME/inc/csrApi.h29
-rw-r--r--drivers/staging/prima/CORE/SME/inc/csrInternal.h24
-rw-r--r--drivers/staging/prima/CORE/SME/inc/csrNeighborRoam.h31
-rw-r--r--drivers/staging/prima/CORE/SME/inc/csr_roam_mbb.h41
-rw-r--r--drivers/staging/prima/CORE/SME/inc/pmc.h3
-rw-r--r--drivers/staging/prima/CORE/SME/inc/smeInside.h2
-rw-r--r--drivers/staging/prima/CORE/SME/inc/smeInternal.h9
-rw-r--r--drivers/staging/prima/CORE/SME/inc/sme_Api.h86
-rw-r--r--drivers/staging/prima/CORE/SME/inc/sme_FTApi.h8
-rw-r--r--drivers/staging/prima/CORE/SME/inc/sme_Trace.h5
-rw-r--r--drivers/staging/prima/CORE/SME/src/csr/csrApiRoam.c1034
-rw-r--r--drivers/staging/prima/CORE/SME/src/csr/csrApiScan.c28
-rw-r--r--drivers/staging/prima/CORE/SME/src/csr/csrCmdProcess.c6
-rw-r--r--drivers/staging/prima/CORE/SME/src/csr/csrInsideApi.h24
-rw-r--r--drivers/staging/prima/CORE/SME/src/csr/csrNeighborRoam.c85
-rw-r--r--drivers/staging/prima/CORE/SME/src/csr/csr_roam_mbb.c890
-rw-r--r--drivers/staging/prima/CORE/SME/src/pmc/pmc.c44
-rw-r--r--drivers/staging/prima/CORE/SME/src/pmc/pmcApi.c70
-rw-r--r--drivers/staging/prima/CORE/SME/src/pmc/pmcLogDump.c3
-rw-r--r--drivers/staging/prima/CORE/SME/src/sme_common/sme_Api.c799
-rw-r--r--drivers/staging/prima/CORE/SME/src/sme_common/sme_FTApi.c31
-rw-r--r--drivers/staging/prima/CORE/SVC/inc/wlan_btc_svc.h3
-rw-r--r--drivers/staging/prima/CORE/SVC/src/btc/wlan_btc_svc.c17
-rw-r--r--drivers/staging/prima/CORE/SYS/legacy/src/utils/src/dot11f.c1495
-rw-r--r--drivers/staging/prima/CORE/SYS/legacy/src/utils/src/macTrace.c32
-rw-r--r--drivers/staging/prima/CORE/SYS/legacy/src/utils/src/parserApi.c165
-rw-r--r--drivers/staging/prima/CORE/SYS/legacy/src/utils/src/utilsParser.c4
-rw-r--r--drivers/staging/prima/CORE/TL/inc/wlan_qct_tl.h46
-rwxr-xr-x[-rw-r--r--]drivers/staging/prima/CORE/TL/src/wlan_qct_tl.c594
-rw-r--r--drivers/staging/prima/CORE/TL/src/wlan_qct_tl_ba.c5
-rw-r--r--drivers/staging/prima/CORE/TL/src/wlan_qct_tli.h43
-rw-r--r--drivers/staging/prima/CORE/VOSS/inc/event_defs.h4
-rw-r--r--drivers/staging/prima/CORE/VOSS/inc/vos_api.h10
-rw-r--r--drivers/staging/prima/CORE/VOSS/inc/vos_diag_core_event.h44
-rw-r--r--drivers/staging/prima/CORE/VOSS/inc/vos_packet.h10
-rw-r--r--drivers/staging/prima/CORE/VOSS/inc/vos_timer.h16
-rw-r--r--drivers/staging/prima/CORE/VOSS/src/vos_api.c287
-rw-r--r--drivers/staging/prima/CORE/VOSS/src/vos_diag.c2
-rw-r--r--drivers/staging/prima/CORE/VOSS/src/vos_sched.h2
-rw-r--r--drivers/staging/prima/CORE/WDA/inc/legacy/halMsgApi.h30
-rw-r--r--drivers/staging/prima/CORE/WDA/inc/legacy/halTypes.h8
-rw-r--r--drivers/staging/prima/CORE/WDA/inc/wlan_qct_wda.h43
-rw-r--r--drivers/staging/prima/CORE/WDA/src/wlan_qct_wda.c1583
-rw-r--r--drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi.h280
-rw-r--r--drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_bd.h11
-rw-r--r--drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_dp.h4
-rw-r--r--drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_i.h173
-rw-r--r--drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_sta.h95
-rw-r--r--drivers/staging/prima/CORE/WDI/CP/src/wlan_qct_wdi.c1547
-rw-r--r--drivers/staging/prima/CORE/WDI/CP/src/wlan_qct_wdi_sta.c17
-rw-r--r--drivers/staging/prima/CORE/WDI/DP/inc/wlan_qct_wdi_ds.h96
-rw-r--r--drivers/staging/prima/CORE/WDI/TRP/DTS/src/wlan_qct_wdi_dts.c49
-rw-r--r--drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_api.c8
-rw-r--r--drivers/staging/prima/Kbuild40
-rw-r--r--drivers/staging/prima/Kconfig4
-rw-r--r--drivers/staging/prima/firmware_bin/WCNSS_qcom_cfg.ini46
-rw-r--r--drivers/staging/prima/riva/inc/wlan_hal_cfg.h13
-rw-r--r--drivers/staging/prima/riva/inc/wlan_hal_msg.h308
-rw-r--r--drivers/target/target_core_fabric_configfs.c5
-rw-r--r--drivers/target/target_core_tpg.c3
-rw-r--r--drivers/tty/serial/efm32-uart.c11
-rw-r--r--drivers/tty/serial/ifx6x60.c2
-rw-r--r--drivers/tty/vt/vt.c6
-rw-r--r--drivers/usb/chipidea/debug.c3
-rw-r--r--drivers/usb/core/hub.c23
-rw-r--r--drivers/usb/dwc3/gadget.c19
-rw-r--r--drivers/usb/gadget/composite.c5
-rw-r--r--drivers/usb/host/r8a66597-hcd.c6
-rw-r--r--drivers/usb/misc/ks_bridge.c2
-rw-r--r--drivers/usb/renesas_usbhs/common.c4
-rw-r--r--drivers/usb/renesas_usbhs/fifo.c50
-rw-r--r--drivers/usb/renesas_usbhs/pipe.c13
-rw-r--r--drivers/usb/renesas_usbhs/pipe.h4
-rw-r--r--drivers/usb/serial/console.c1
-rw-r--r--drivers/video/cfbimgblt.c153
-rw-r--r--drivers/video/fbmem.c7
-rw-r--r--drivers/video/msm/mdss/mdp3_ppp.c6
-rw-r--r--drivers/video/msm/mdss/mdss_edp.c11
-rw-r--r--drivers/video/msm/mdss/mdss_fb.c24
-rw-r--r--drivers/video/msm/mdss/mdss_mdp_intf_video.c7
-rw-r--r--drivers/video/msm/mdss/mdss_mdp_overlay.c17
-rw-r--r--drivers/video/msm/mdss/mdss_mdp_pp.c14
-rw-r--r--fs/9p/acl.c3
-rw-r--r--fs/aio.c4
-rw-r--r--fs/btrfs/acl.c3
-rw-r--r--fs/btrfs/ioctl.c4
-rw-r--r--fs/direct-io.c4
-rw-r--r--fs/eventpoll.c4
-rw-r--r--fs/exec.c28
-rw-r--r--fs/ext2/acl.c3
-rw-r--r--fs/ext3/acl.c12
-rw-r--r--fs/ext4/Kconfig18
-rw-r--r--fs/ext4/Makefile2
-rw-r--r--fs/ext4/acl.c3
-rw-r--r--fs/ext4/ext4.h5
-rw-r--r--fs/ext4/ext4_jbd2.c8
-rw-r--r--fs/ext4/file.c57
-rw-r--r--fs/ext4/inode.c11
-rw-r--r--fs/ext4/namei.c20
-rw-r--r--fs/ext4/readpage.c264
-rw-r--r--fs/ext4/resize.c3
-rw-r--r--fs/ext4/super.c19
-rw-r--r--fs/ext4/xattr.c19
-rw-r--r--fs/ext4/xattr.h3
-rw-r--r--fs/f2fs/acl.c6
l---------fs/f2fs~a6f9f264ace7... fs: use motorola_kernel1
-rw-r--r--fs/fs-writeback.c2
-rw-r--r--fs/fscache/object-list.c7
-rw-r--r--fs/fuse/file.c2
-rw-r--r--fs/fuse/inode.c2
-rw-r--r--fs/generic_acl.c10
-rw-r--r--fs/gfs2/acl.c4
-rw-r--r--fs/inode.c31
-rw-r--r--fs/jfs/xattr.c3
-rw-r--r--fs/namespace.c14
-rw-r--r--fs/ocfs2/acl.c16
-rw-r--r--fs/posix_acl.c62
-rw-r--r--fs/pstore/ram_core.c2
-rw-r--r--fs/reiserfs/xattr_acl.c3
-rwxr-xr-xfs/sdcardfs/derived_perm.c3
-rwxr-xr-xfs/sdcardfs/file.c10
-rwxr-xr-xfs/sdcardfs/inode.c12
-rwxr-xr-xfs/sdcardfs/main.c7
-rwxr-xr-xfs/sdcardfs/sdcardfs.h1
-rwxr-xr-xfs/sdcardfs/super.c2
-rw-r--r--fs/super.c6
-rw-r--r--fs/ubifs/dir.c17
-rw-r--r--fs/udf/inode.c26
-rw-r--r--fs/xfs/xfs_acl.c4
-rw-r--r--include/asm-generic/percpu.h3
-rw-r--r--include/linux/blkdev.h2
-rw-r--r--include/linux/buffer_head.h12
-rw-r--r--include/linux/compiler-gcc.h115
-rw-r--r--include/linux/compiler-gcc3.h23
-rw-r--r--include/linux/compiler-gcc4.h91
-rw-r--r--include/linux/compiler-gcc5.h67
-rw-r--r--include/linux/cpufreq.h1
-rw-r--r--include/linux/fs.h10
-rw-r--r--include/linux/i2c/i2c-msm-v2.h3
-rw-r--r--include/linux/kernel.h6
-rw-r--r--include/linux/key.h2
-rw-r--r--include/linux/mm.h6
-rwxr-xr-x[-rw-r--r--]include/linux/mmc/sdio_func.h0
-rw-r--r--include/linux/page-flags.h23
-rw-r--r--include/linux/posix_acl.h4
-rw-r--r--include/linux/preempt.h25
-rw-r--r--include/linux/topology.h2
-rw-r--r--include/linux/tracepoint.h3
-rw-r--r--include/linux/wait.h30
-rw-r--r--include/linux/workqueue.h39
-rw-r--r--include/net/fib_rules.h11
-rw-r--r--include/net/flow.h13
-rw-r--r--include/net/ip.h2
-rw-r--r--include/net/ip6_route.h5
-rw-r--r--include/net/ipv6.h1
-rw-r--r--include/net/iw_handler.h3
-rw-r--r--include/net/route.h5
-rw-r--r--include/net/sctp/sctp.h4
-rw-r--r--include/net/sctp/ulpevent.h6
-rw-r--r--include/net/tcp.h10
-rw-r--r--include/sound/msm-dts-eagle.h148
-rw-r--r--include/sound/q6adm-v2.h3
-rw-r--r--include/target/target_core_base.h1
-rw-r--r--include/uapi/linux/android/binder.h2
-rw-r--r--include/uapi/linux/fib_rules.h10
-rw-r--r--include/uapi/linux/rtnetlink.h9
-rw-r--r--init/main.c2
-rw-r--r--kernel/audit.c4
-rw-r--r--kernel/events/core.c80
-rw-r--r--kernel/extable.c2
-rw-r--r--kernel/irq/proc.c19
-rw-r--r--kernel/power/Kconfig20
-rw-r--r--kernel/rcu/srcu.c5
-rw-r--r--kernel/sched/core.c116
-rw-r--r--kernel/sched/cputime.c4
-rw-r--r--kernel/sched/fair.c11
-rw-r--r--kernel/sched/wait.c9
-rw-r--r--kernel/softirq.c4
-rw-r--r--kernel/sys.c20
-rw-r--r--kernel/sysctl.c3
-rw-r--r--kernel/time/ntp.c5
-rw-r--r--kernel/timer.c8
-rw-r--r--kernel/trace/trace.c12
-rw-r--r--kernel/trace/trace_printk.c5
-rw-r--r--kernel/workqueue.c47
-rw-r--r--lib/cmdline.c6
-rw-r--r--lib/digsig.c6
-rw-r--r--lib/int_sqrt.c33
-rw-r--r--lib/locking-selftest.c2
-rw-r--r--lib/lz4/lz4_decompress.c39
-rw-r--r--lib/lz4/lz4defs.h26
-rw-r--r--lib/smp_processor_id.c3
-rw-r--r--lib/vsprintf.c150
-rw-r--r--mm/Kconfig10
-rw-r--r--mm/ksm.c33
-rw-r--r--mm/mmap.c2
-rw-r--r--mm/page-writeback.c13
-rw-r--r--mm/page_alloc.c7
-rw-r--r--mm/vmstat.c4
-rw-r--r--net/8021q/vlan.c3
-rw-r--r--net/bluetooth/bnep/core.c4
-rw-r--r--net/bluetooth/cmtp/core.c3
-rw-r--r--net/core/dev.c31
-rw-r--r--net/core/fib_rules.c95
-rw-r--r--net/core/neighbour.c5
-rw-r--r--net/core/rtnetlink.c10
-rw-r--r--net/core/sock.c2
-rw-r--r--net/ipv4/af_inet.c2
-rw-r--r--net/ipv4/devinet.c10
-rw-r--r--net/ipv4/fib_frontend.c9
-rw-r--r--net/ipv4/icmp.c2
-rw-r--r--net/ipv4/inet_connection_sock.c4
-rw-r--r--net/ipv4/ip_output.c7
-rw-r--r--net/ipv4/netfilter/nf_nat_snmp_basic.c1
-rw-r--r--net/ipv4/ping.c2
-rw-r--r--net/ipv4/raw.c3
-rw-r--r--net/ipv4/route.c49
-rw-r--r--net/ipv4/syncookies.c3
-rw-r--r--net/ipv4/tcp.c6
-rw-r--r--net/ipv4/tcp_cong.c1
-rw-r--r--net/ipv4/tcp_input.c36
-rw-r--r--net/ipv4/tcp_ipv4.c14
-rw-r--r--net/ipv4/tcp_output.c32
-rw-r--r--net/ipv4/udp.c4
-rw-r--r--net/ipv4/xfrm4_policy.c1
-rw-r--r--net/ipv6/addrconf.c3
-rw-r--r--net/ipv6/af_inet6.c2
-rw-r--r--net/ipv6/ah6.c4
-rw-r--r--net/ipv6/datagram.c2
-rw-r--r--net/ipv6/esp6.c4
-rw-r--r--net/ipv6/icmp.c6
-rw-r--r--net/ipv6/inet6_connection_sock.c3
-rw-r--r--net/ipv6/ip6_fib.c25
-rw-r--r--net/ipv6/ip6_gre.c8
-rw-r--r--net/ipv6/ip6_output.c7
-rw-r--r--net/ipv6/ip6_tunnel.c3
-rw-r--r--net/ipv6/ipcomp6.c4
-rw-r--r--net/ipv6/netfilter.c1
-rw-r--r--net/ipv6/ping.c2
-rw-r--r--net/ipv6/raw.c4
-rw-r--r--net/ipv6/route.c17
-rw-r--r--net/ipv6/syncookies.c2
-rw-r--r--net/ipv6/tcp_ipv6.c11
-rw-r--r--net/ipv6/udp.c2
-rw-r--r--net/key/af_key.c17
-rw-r--r--net/l2tp/l2tp_ip6.c1
-rw-r--r--net/netfilter/ipvs/ip_vs_core.c19
-rw-r--r--net/netfilter/nf_conntrack_ecache.c2
-rw-r--r--net/netfilter/nf_conntrack_extend.c13
-rw-r--r--net/netfilter/nf_conntrack_netlink.c1
-rw-r--r--net/netfilter/nf_nat_core.c2
-rw-r--r--net/netfilter/nfnetlink_cttimeout.c1
-rw-r--r--net/netfilter/xt_TCPMSS.c6
-rw-r--r--net/netfilter/xt_qtaguid.c19
-rw-r--r--net/packet/af_packet.c15
-rw-r--r--net/rfkill/core.c9
-rw-r--r--net/rxrpc/ar-key.c64
-rw-r--r--net/sctp/ipv6.c2
-rw-r--r--net/wireless/core.h1
-rw-r--r--net/wireless/nl80211.c13
-rw-r--r--net/wireless/reg.c7
-rw-r--r--net/wireless/scan.c71
-rw-r--r--net/xfrm/xfrm_policy.c6
-rw-r--r--net/xfrm/xfrm_user.c3
-rwxr-xr-xscripts/setlocalversion2
-rw-r--r--security/keys/encrypted-keys/encrypted.c9
-rw-r--r--security/keys/internal.h2
-rw-r--r--security/keys/key.c12
-rw-r--r--security/keys/keyctl.c4
-rw-r--r--security/keys/keyring.c23
-rw-r--r--security/keys/process_keys.c8
-rw-r--r--security/selinux/avc.c2
-rw-r--r--security/selinux/hooks.c9
-rw-r--r--sound/core/compress_offload.c16
-rw-r--r--sound/core/control.c2
-rw-r--r--sound/soc/msm/qdsp6v2/Makefile1
-rw-r--r--sound/soc/msm/qdsp6v2/audio_cal_utils.c12
-rw-r--r--sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c91
-rw-r--r--sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c76
-rw-r--r--sound/soc/msm/qdsp6v2/msm-dts-eagle.c1655
-rw-r--r--sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.c4
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-routing-devdep.c41
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c11
-rw-r--r--sound/soc/msm/qdsp6v2/q6adm.c260
-rw-r--r--sound/soc/msm/qdsp6v2/q6afe.c4
-rw-r--r--sound/soc/msm/qdsp6v2/q6asm.c229
-rw-r--r--sound/soc/msm/qdsp6v2/q6core.c113
-rw-r--r--sound/soc/soc-compress.c5
-rw-r--r--sound/soc/soc-jack.c9
-rw-r--r--sound/soc/soc-pcm.c5
-rw-r--r--tools/perf/ui/browser.c2
544 files changed, 24493 insertions, 7633 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 188d46e13d4..b679a62dab5 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -3390,21 +3390,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
that this also can be controlled per-workqueue for
workqueues visible under /sys/bus/workqueue/.
- workqueue.power_efficient
- Per-cpu workqueues are generally preferred because
- they show better performance thanks to cache
- locality; unfortunately, per-cpu workqueues tend to
- be more power hungry than unbound workqueues.
-
- Enabling this makes the per-cpu workqueues which
- were observed to contribute significantly to power
- consumption unbound, leading to measurably lower
- power usage at the cost of small performance
- overhead.
-
- The default value of this parameter is determined by
- the config option CONFIG_WQ_POWER_EFFICIENT_DEFAULT.
-
x2apic_phys [X86-64,APIC] Use x2apic physical mode instead of
default x2apic cluster mode on platforms
supporting x2apic.
diff --git a/Documentation/printk-formats.txt b/Documentation/printk-formats.txt
index 3f35e2dc34a..3af5ae6c9c1 100644
--- a/Documentation/printk-formats.txt
+++ b/Documentation/printk-formats.txt
@@ -45,11 +45,6 @@ Kernel Pointers:
users. The behaviour of %pK depends on the kptr_restrict sysctl - see
Documentation/sysctl/kernel.txt for more details.
- %pP 0x01234567 or 0x0123456789abcdef
-
- For printing kernel pointers which should always be shown, even to
- unprivileged users.
-
Struct Resources:
%pr [mem 0x60000000-0x6fffffff flags 0x2200] or
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
index 0eb7cb99537..d438fd2c21a 100644
--- a/Documentation/sysctl/kernel.txt
+++ b/Documentation/sysctl/kernel.txt
@@ -334,15 +334,6 @@ values to unprivileged users is a concern.
When kptr_restrict is set to (2), kernel pointers printed using
%pK will be replaced with 0's regardless of privileges.
-When kptr_restrict is set to (3), kernel pointers printed using
-%p and %pK will be replaced with 0's regardless of privileges,
-however kernel pointers printed using %pP will continue to be printed.
-
-When kptr_restrict is set to (4), kernel pointers printed with
-%p, %pK, %pa, and %p[rR] will be replaced with 0's regardless of
-privileges. Kernel pointers printed using %pP will continue to be
-printed.
-
==============================================================
kstack_depth_to_print: (X86 only)
diff --git a/MAINTAINERS b/MAINTAINERS
index 5bcf562c019..c54de5f47e3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7139,6 +7139,16 @@ S: Maintained
F: drivers/mmc/host/sdhci.*
F: drivers/mmc/host/sdhci-pltfm.[ch]
+SECURE COMPUTING
+M: Kees Cook <keescook@chromium.org>
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git seccomp
+S: Supported
+F: kernel/seccomp.c
+F: include/uapi/linux/seccomp.h
+F: include/linux/seccomp.h
+K: \bsecure_computing
+K: \bTIF_SECCOMP\b
+
SECURE DIGITAL HOST CONTROLLER INTERFACE, OPEN FIRMWARE BINDINGS (SDHCI-OF)
M: Anton Vorontsov <avorontsov@ru.mvista.com>
L: linuxppc-dev@lists.ozlabs.org
diff --git a/Makefile b/Makefile
index 72dfe021df0..f29988bb8c3 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
VERSION = 3
PATCHLEVEL = 10
-SUBLEVEL = 107
+SUBLEVEL = 108
EXTRAVERSION =
-NAME = TOSSUG Baby Fish
+NAME = END-OF-LIFE
# *DOCUMENTATION*
# To see a list of typical targets execute "make help"
@@ -331,7 +331,7 @@ include $(srctree)/scripts/Kbuild.include
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
-CC = $(CROSS_COMPILE)gcc
+REAL_CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
@@ -345,6 +345,10 @@ DEPMOD = /sbin/depmod
PERL = perl
CHECK = sparse
+# Use the wrapper for the compiler. This wrapper scans for new
+# warnings and causes the build to stop upon encountering them.
+CC = $(srctree)/scripts/gcc-wrapper.py $(REAL_CC)
+
CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \
-Wbitwise -Wno-return-void $(CF)
CFLAGS_MODULE =
diff --git a/android/configs/android-base.cfg b/android/configs/android-base.cfg
index 644f8f8b6a3..abe92f78f65 100644
--- a/android/configs/android-base.cfg
+++ b/android/configs/android-base.cfg
@@ -1,4 +1,6 @@
# KEEP ALPHABETICALLY SORTED
+# CONFIG_DEVKMEM is not set
+# CONFIG_DEVMEM is not set
# CONFIG_INET_LRO is not set
# CONFIG_MODULES is not set
# CONFIG_NFSD is not set
diff --git a/arch/arm/boot/dts/qcom/msm8952-gpu.dtsi b/arch/arm/boot/dts/qcom/msm8952-gpu.dtsi
index 4007ab1593c..b7a0995769c 100644
--- a/arch/arm/boot/dts/qcom/msm8952-gpu.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8952-gpu.dtsi
@@ -56,7 +56,7 @@
qcom,chipid = <0x04000510>;
- qcom,initial-pwrlevel = <4>;
+ qcom,initial-pwrlevel = <3>;
qcom,idle-timeout = <80>; //msecs
qcom,strtstp-sleepwake;
diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
index ce01364a96e..992d4046bb8 100644
--- a/arch/arm/common/Kconfig
+++ b/arch/arm/common/Kconfig
@@ -21,3 +21,49 @@ config SHARP_SCOOP
config FIQ_GLUE
bool
select FIQ
+
+config FIQ_DEBUGGER
+ bool "FIQ Mode Serial Debugger"
+ select FIQ
+ select FIQ_GLUE
+ default n
+ help
+ The FIQ serial debugger can accept commands even when the
+ kernel is unresponsive due to being stuck with interrupts
+ disabled.
+
+
+config FIQ_DEBUGGER_NO_SLEEP
+ bool "Keep serial debugger active"
+ depends on FIQ_DEBUGGER
+ default n
+ help
+ Enables the serial debugger at boot. Passing
+ fiq_debugger.no_sleep on the kernel commandline will
+ override this config option.
+
+config FIQ_DEBUGGER_WAKEUP_IRQ_ALWAYS_ON
+ bool "Don't disable wakeup IRQ when debugger is active"
+ depends on FIQ_DEBUGGER
+ default n
+ help
+ Don't disable the wakeup irq when enabling the uart clock. This will
+ cause extra interrupts, but it makes the serial debugger usable with
+ on some MSM radio builds that ignore the uart clock request in power
+ collapse.
+
+config FIQ_DEBUGGER_CONSOLE
+ bool "Console on FIQ Serial Debugger port"
+ depends on FIQ_DEBUGGER
+ default n
+ help
+ Enables a console so that printk messages are displayed on
+ the debugger serial port as the occur.
+
+config FIQ_DEBUGGER_CONSOLE_DEFAULT_ENABLE
+ bool "Put the FIQ debugger into console mode by default"
+ depends on FIQ_DEBUGGER_CONSOLE
+ default n
+ help
+ If enabled, this puts the fiq debugger into console mode by default.
+ Otherwise, the fiq debugger will start out in debug mode.
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index 76e765d1856..a5bb6641670 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -4,6 +4,7 @@
obj-y += firmware.o
+obj-$(CONFIG_FIQ_DEBUGGER) += fiq_debugger.o
obj-$(CONFIG_FIQ_GLUE) += fiq_glue.o fiq_glue_setup.o
obj-$(CONFIG_ICST) += icst.o
obj-$(CONFIG_SA1111) += sa1111.o
diff --git a/arch/arm/common/fiq_debugger.c b/arch/arm/common/fiq_debugger.c
new file mode 100644
index 00000000000..65b943c7630
--- /dev/null
+++ b/arch/arm/common/fiq_debugger.c
@@ -0,0 +1,1376 @@
+/*
+ * arch/arm/common/fiq_debugger.c
+ *
+ * Serial Debugger Interface accessed through an FIQ interrupt.
+ *
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+
+#include <stdarg.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/console.h>
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/kernel_stat.h>
+#include <linux/kmsg_dump.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/reboot.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/smp.h>
+#include <linux/timer.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/wakelock.h>
+
+#include <asm/fiq_debugger.h>
+#include <asm/fiq_glue.h>
+#include <asm/stacktrace.h>
+
+#include <linux/uaccess.h>
+
+#include "fiq_debugger_ringbuf.h"
+
+#define DEBUG_MAX 64
+#define MAX_UNHANDLED_FIQ_COUNT 1000000
+
+#define MAX_FIQ_DEBUGGER_PORTS 4
+
+#define THREAD_INFO(sp) ((struct thread_info *) \
+ ((unsigned long)(sp) & ~(THREAD_SIZE - 1)))
+
+struct fiq_debugger_state {
+ struct fiq_glue_handler handler;
+
+ int fiq;
+ int uart_irq;
+ int signal_irq;
+ int wakeup_irq;
+ bool wakeup_irq_no_set_wake;
+ struct clk *clk;
+ struct fiq_debugger_pdata *pdata;
+ struct platform_device *pdev;
+
+ char debug_cmd[DEBUG_MAX];
+ int debug_busy;
+ int debug_abort;
+
+ char debug_buf[DEBUG_MAX];
+ int debug_count;
+
+ bool no_sleep;
+ bool debug_enable;
+ bool ignore_next_wakeup_irq;
+ struct timer_list sleep_timer;
+ spinlock_t sleep_timer_lock;
+ bool uart_enabled;
+ struct wake_lock debugger_wake_lock;
+ bool console_enable;
+ int current_cpu;
+ atomic_t unhandled_fiq_count;
+ bool in_fiq;
+
+ struct work_struct work;
+ spinlock_t work_lock;
+ char work_cmd[DEBUG_MAX];
+
+#ifdef CONFIG_FIQ_DEBUGGER_CONSOLE
+ spinlock_t console_lock;
+ struct console console;
+ struct tty_port tty_port;
+ struct fiq_debugger_ringbuf *tty_rbuf;
+ bool syslog_dumping;
+#endif
+
+ unsigned int last_irqs[NR_IRQS];
+ unsigned int last_local_timer_irqs[NR_CPUS];
+};
+
+#ifdef CONFIG_FIQ_DEBUGGER_CONSOLE
+struct tty_driver *fiq_tty_driver;
+#endif
+
+#ifdef CONFIG_FIQ_DEBUGGER_NO_SLEEP
+static bool initial_no_sleep = true;
+#else
+static bool initial_no_sleep;
+#endif
+
+#ifdef CONFIG_FIQ_DEBUGGER_CONSOLE_DEFAULT_ENABLE
+static bool initial_debug_enable = true;
+static bool initial_console_enable = true;
+#else
+static bool initial_debug_enable;
+static bool initial_console_enable;
+#endif
+
+static bool fiq_kgdb_enable;
+
+module_param_named(no_sleep, initial_no_sleep, bool, 0644);
+module_param_named(debug_enable, initial_debug_enable, bool, 0644);
+module_param_named(console_enable, initial_console_enable, bool, 0644);
+module_param_named(kgdb_enable, fiq_kgdb_enable, bool, 0644);
+
+#ifdef CONFIG_FIQ_DEBUGGER_WAKEUP_IRQ_ALWAYS_ON
+static inline void enable_wakeup_irq(struct fiq_debugger_state *state) {}
+static inline void disable_wakeup_irq(struct fiq_debugger_state *state) {}
+#else
+static inline void enable_wakeup_irq(struct fiq_debugger_state *state)
+{
+ if (state->wakeup_irq < 0)
+ return;
+ enable_irq(state->wakeup_irq);
+ if (!state->wakeup_irq_no_set_wake)
+ enable_irq_wake(state->wakeup_irq);
+}
+static inline void disable_wakeup_irq(struct fiq_debugger_state *state)
+{
+ if (state->wakeup_irq < 0)
+ return;
+ disable_irq_nosync(state->wakeup_irq);
+ if (!state->wakeup_irq_no_set_wake)
+ disable_irq_wake(state->wakeup_irq);
+}
+#endif
+
+static bool inline debug_have_fiq(struct fiq_debugger_state *state)
+{
+ return (state->fiq >= 0);
+}
+
+static void debug_force_irq(struct fiq_debugger_state *state)
+{
+ unsigned int irq = state->signal_irq;
+
+ if (WARN_ON(!debug_have_fiq(state)))
+ return;
+ if (state->pdata->force_irq) {
+ state->pdata->force_irq(state->pdev, irq);
+ } else {
+ struct irq_chip *chip = irq_get_chip(irq);
+ if (chip && chip->irq_retrigger)
+ chip->irq_retrigger(irq_get_irq_data(irq));
+ }
+}
+
+static void debug_uart_enable(struct fiq_debugger_state *state)
+{
+ if (state->clk)
+ clk_enable(state->clk);
+ if (state->pdata->uart_enable)
+ state->pdata->uart_enable(state->pdev);
+}
+
+static void debug_uart_disable(struct fiq_debugger_state *state)
+{
+ if (state->pdata->uart_disable)
+ state->pdata->uart_disable(state->pdev);
+ if (state->clk)
+ clk_disable(state->clk);
+}
+
+static void debug_uart_flush(struct fiq_debugger_state *state)
+{
+ if (state->pdata->uart_flush)
+ state->pdata->uart_flush(state->pdev);
+}
+
+static void debug_putc(struct fiq_debugger_state *state, char c)
+{
+ state->pdata->uart_putc(state->pdev, c);
+}
+
+static void debug_puts(struct fiq_debugger_state *state, char *s)
+{
+ unsigned c;
+ while ((c = *s++)) {
+ if (c == '\n')
+ debug_putc(state, '\r');
+ debug_putc(state, c);
+ }
+}
+
+static void debug_prompt(struct fiq_debugger_state *state)
+{
+ debug_puts(state, "debug> ");
+}
+
+static void dump_kernel_log(struct fiq_debugger_state *state)
+{
+ char buf[512];
+ size_t len;
+ struct kmsg_dumper dumper = { .active = true };
+
+
+ kmsg_dump_rewind_nolock(&dumper);
+ while (kmsg_dump_get_line_nolock(&dumper, true, buf,
+ sizeof(buf) - 1, &len)) {
+ buf[len] = 0;
+ debug_puts(state, buf);
+ }
+}
+
+static char *mode_name(unsigned cpsr)
+{
+ switch (cpsr & MODE_MASK) {
+ case USR_MODE: return "USR";
+ case FIQ_MODE: return "FIQ";
+ case IRQ_MODE: return "IRQ";
+ case SVC_MODE: return "SVC";
+ case ABT_MODE: return "ABT";
+ case UND_MODE: return "UND";
+ case SYSTEM_MODE: return "SYS";
+ default: return "???";
+ }
+}
+
+static int debug_printf(void *cookie, const char *fmt, ...)
+{
+ struct fiq_debugger_state *state = cookie;
+ char buf[256];
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsnprintf(buf, sizeof(buf), fmt, ap);
+ va_end(ap);
+
+ debug_puts(state, buf);
+ return state->debug_abort;
+}
+
+/* Safe outside fiq context */
+static int debug_printf_nfiq(void *cookie, const char *fmt, ...)
+{
+ struct fiq_debugger_state *state = cookie;
+ char buf[256];
+ va_list ap;
+ unsigned long irq_flags;
+
+ va_start(ap, fmt);
+ vsnprintf(buf, 128, fmt, ap);
+ va_end(ap);
+
+ local_irq_save(irq_flags);
+ debug_puts(state, buf);
+ debug_uart_flush(state);
+ local_irq_restore(irq_flags);
+ return state->debug_abort;
+}
+
+static void dump_regs(struct fiq_debugger_state *state, unsigned *regs)
+{
+ debug_printf(state, " r0 %08x r1 %08x r2 %08x r3 %08x\n",
+ regs[0], regs[1], regs[2], regs[3]);
+ debug_printf(state, " r4 %08x r5 %08x r6 %08x r7 %08x\n",
+ regs[4], regs[5], regs[6], regs[7]);
+ debug_printf(state, " r8 %08x r9 %08x r10 %08x r11 %08x mode %s\n",
+ regs[8], regs[9], regs[10], regs[11],
+ mode_name(regs[16]));
+ if ((regs[16] & MODE_MASK) == USR_MODE)
+ debug_printf(state, " ip %08x sp %08x lr %08x pc %08x "
+ "cpsr %08x\n", regs[12], regs[13], regs[14],
+ regs[15], regs[16]);
+ else
+ debug_printf(state, " ip %08x sp %08x lr %08x pc %08x "
+ "cpsr %08x spsr %08x\n", regs[12], regs[13],
+ regs[14], regs[15], regs[16], regs[17]);
+}
+
+struct mode_regs {
+ unsigned long sp_svc;
+ unsigned long lr_svc;
+ unsigned long spsr_svc;
+
+ unsigned long sp_abt;
+ unsigned long lr_abt;
+ unsigned long spsr_abt;
+
+ unsigned long sp_und;
+ unsigned long lr_und;
+ unsigned long spsr_und;
+
+ unsigned long sp_irq;
+ unsigned long lr_irq;
+ unsigned long spsr_irq;
+
+ unsigned long r8_fiq;
+ unsigned long r9_fiq;
+ unsigned long r10_fiq;
+ unsigned long r11_fiq;
+ unsigned long r12_fiq;
+ unsigned long sp_fiq;
+ unsigned long lr_fiq;
+ unsigned long spsr_fiq;
+};
+
+void __naked get_mode_regs(struct mode_regs *regs)
+{
+ asm volatile (
+ "mrs r1, cpsr\n"
+ "msr cpsr_c, #0xd3 @(SVC_MODE | PSR_I_BIT | PSR_F_BIT)\n"
+ "stmia r0!, {r13 - r14}\n"
+ "mrs r2, spsr\n"
+ "msr cpsr_c, #0xd7 @(ABT_MODE | PSR_I_BIT | PSR_F_BIT)\n"
+ "stmia r0!, {r2, r13 - r14}\n"
+ "mrs r2, spsr\n"
+ "msr cpsr_c, #0xdb @(UND_MODE | PSR_I_BIT | PSR_F_BIT)\n"
+ "stmia r0!, {r2, r13 - r14}\n"
+ "mrs r2, spsr\n"
+ "msr cpsr_c, #0xd2 @(IRQ_MODE | PSR_I_BIT | PSR_F_BIT)\n"
+ "stmia r0!, {r2, r13 - r14}\n"
+ "mrs r2, spsr\n"
+ "msr cpsr_c, #0xd1 @(FIQ_MODE | PSR_I_BIT | PSR_F_BIT)\n"
+ "stmia r0!, {r2, r8 - r14}\n"
+ "mrs r2, spsr\n"
+ "stmia r0!, {r2}\n"
+ "msr cpsr_c, r1\n"
+ "bx lr\n");
+}
+
+
+static void dump_allregs(struct fiq_debugger_state *state, unsigned *regs)
+{
+ struct mode_regs mode_regs;
+ dump_regs(state, regs);
+ get_mode_regs(&mode_regs);
+ debug_printf(state, " svc: sp %08x lr %08x spsr %08x\n",
+ mode_regs.sp_svc, mode_regs.lr_svc, mode_regs.spsr_svc);
+ debug_printf(state, " abt: sp %08x lr %08x spsr %08x\n",
+ mode_regs.sp_abt, mode_regs.lr_abt, mode_regs.spsr_abt);
+ debug_printf(state, " und: sp %08x lr %08x spsr %08x\n",
+ mode_regs.sp_und, mode_regs.lr_und, mode_regs.spsr_und);
+ debug_printf(state, " irq: sp %08x lr %08x spsr %08x\n",
+ mode_regs.sp_irq, mode_regs.lr_irq, mode_regs.spsr_irq);
+ debug_printf(state, " fiq: r8 %08x r9 %08x r10 %08x r11 %08x "
+ "r12 %08x\n",
+ mode_regs.r8_fiq, mode_regs.r9_fiq, mode_regs.r10_fiq,
+ mode_regs.r11_fiq, mode_regs.r12_fiq);
+ debug_printf(state, " fiq: sp %08x lr %08x spsr %08x\n",
+ mode_regs.sp_fiq, mode_regs.lr_fiq, mode_regs.spsr_fiq);
+}
+
+static void dump_irqs(struct fiq_debugger_state *state)
+{
+ int n;
+ struct irq_desc *desc;
+
+ debug_printf(state, "irqnr total since-last status name\n");
+ for_each_irq_desc(n, desc) {
+ struct irqaction *act = desc->action;
+ if (!act && !kstat_irqs(n))
+ continue;
+ debug_printf(state, "%5d: %10u %11u %8x %s\n", n,
+ kstat_irqs(n),
+ kstat_irqs(n) - state->last_irqs[n],
+ desc->status_use_accessors,
+ (act && act->name) ? act->name : "???");
+ state->last_irqs[n] = kstat_irqs(n);
+ }
+}
+
+struct stacktrace_state {
+ struct fiq_debugger_state *state;
+ unsigned int depth;
+};
+
+static int report_trace(struct stackframe *frame, void *d)
+{
+ struct stacktrace_state *sts = d;
+
+ if (sts->depth) {
+ debug_printf(sts->state,
+ " pc: %p (%pF), lr %p (%pF), sp %p, fp %p\n",
+ frame->pc, frame->pc, frame->lr, frame->lr,
+ frame->sp, frame->fp);
+ sts->depth--;
+ return 0;
+ }
+ debug_printf(sts->state, " ...\n");
+
+ return sts->depth == 0;
+}
+
+struct frame_tail {
+ struct frame_tail *fp;
+ unsigned long sp;
+ unsigned long lr;
+} __attribute__((packed));
+
+static struct frame_tail *user_backtrace(struct fiq_debugger_state *state,
+ struct frame_tail *tail)
+{
+ struct frame_tail buftail[2];
+
+ /* Also check accessibility of one struct frame_tail beyond */
+ if (!access_ok(VERIFY_READ, tail, sizeof(buftail))) {
+ debug_printf(state, " invalid frame pointer %p\n", tail);
+ return NULL;
+ }
+ if (__copy_from_user_inatomic(buftail, tail, sizeof(buftail))) {
+ debug_printf(state,
+ " failed to copy frame pointer %p\n", tail);
+ return NULL;
+ }
+
+ debug_printf(state, " %p\n", buftail[0].lr);
+
+ /* frame pointers should strictly progress back up the stack
+ * (towards higher addresses) */
+ if (tail >= buftail[0].fp)
+ return NULL;
+
+ return buftail[0].fp-1;
+}
+
+void dump_stacktrace(struct fiq_debugger_state *state,
+ struct pt_regs * const regs, unsigned int depth, void *ssp)
+{
+ struct frame_tail *tail;
+ struct thread_info *real_thread_info = THREAD_INFO(ssp);
+ struct stacktrace_state sts;
+
+ sts.depth = depth;
+ sts.state = state;
+ *current_thread_info() = *real_thread_info;
+
+ if (!current)
+ debug_printf(state, "current NULL\n");
+ else
+ debug_printf(state, "pid: %d comm: %s\n",
+ current->pid, current->comm);
+ dump_regs(state, (unsigned *)regs);
+
+ if (!user_mode(regs)) {
+ struct stackframe frame;
+ frame.fp = regs->ARM_fp;
+ frame.sp = regs->ARM_sp;
+ frame.lr = regs->ARM_lr;
+ frame.pc = regs->ARM_pc;
+ debug_printf(state,
+ " pc: %p (%pF), lr %p (%pF), sp %p, fp %p\n",
+ regs->ARM_pc, regs->ARM_pc, regs->ARM_lr, regs->ARM_lr,
+ regs->ARM_sp, regs->ARM_fp);
+ walk_stackframe(&frame, report_trace, &sts);
+ return;
+ }
+
+ tail = ((struct frame_tail *) regs->ARM_fp) - 1;
+ while (depth-- && tail && !((unsigned long) tail & 3))
+ tail = user_backtrace(state, tail);
+}
+
+static void do_ps(struct fiq_debugger_state *state)
+{
+ struct task_struct *g;
+ struct task_struct *p;
+ unsigned task_state;
+ static const char stat_nam[] = "RSDTtZX";
+
+ debug_printf(state, "pid ppid prio task pc\n");
+ read_lock(&tasklist_lock);
+ do_each_thread(g, p) {
+ task_state = p->state ? __ffs(p->state) + 1 : 0;
+ debug_printf(state,
+ "%5d %5d %4d ", p->pid, p->parent->pid, p->prio);
+ debug_printf(state, "%-13.13s %c", p->comm,
+ task_state >= sizeof(stat_nam) ? '?' : stat_nam[task_state]);
+ if (task_state == TASK_RUNNING)
+ debug_printf(state, " running\n");
+ else
+ debug_printf(state, " %08lx\n", thread_saved_pc(p));
+ } while_each_thread(g, p);
+ read_unlock(&tasklist_lock);
+}
+
+#ifdef CONFIG_FIQ_DEBUGGER_CONSOLE
+static void begin_syslog_dump(struct fiq_debugger_state *state)
+{
+ state->syslog_dumping = true;
+}
+
+static void end_syslog_dump(struct fiq_debugger_state *state)
+{
+ state->syslog_dumping = false;
+}
+#else
+extern int do_syslog(int type, char __user *bug, int count);
+static void begin_syslog_dump(struct fiq_debugger_state *state)
+{
+ do_syslog(5 /* clear */, NULL, 0);
+}
+
+static void end_syslog_dump(struct fiq_debugger_state *state)
+{
+ dump_kernel_log(state);
+}
+#endif
+
+static void do_sysrq(struct fiq_debugger_state *state, char rq)
+{
+ if ((rq == 'g' || rq == 'G') && !fiq_kgdb_enable) {
+ debug_printf(state, "sysrq-g blocked\n");
+ return;
+ }
+ begin_syslog_dump(state);
+ handle_sysrq(rq);
+ end_syslog_dump(state);
+}
+
+#ifdef CONFIG_KGDB
+static void do_kgdb(struct fiq_debugger_state *state)
+{
+ if (!fiq_kgdb_enable) {
+ debug_printf(state, "kgdb through fiq debugger not enabled\n");
+ return;
+ }
+
+ debug_printf(state, "enabling console and triggering kgdb\n");
+ state->console_enable = true;
+ handle_sysrq('g');
+}
+#endif
+
+static void debug_schedule_work(struct fiq_debugger_state *state, char *cmd)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&state->work_lock, flags);
+ if (state->work_cmd[0] != '\0') {
+ debug_printf(state, "work command processor busy\n");
+ spin_unlock_irqrestore(&state->work_lock, flags);
+ return;
+ }
+
+ strlcpy(state->work_cmd, cmd, sizeof(state->work_cmd));
+ spin_unlock_irqrestore(&state->work_lock, flags);
+
+ schedule_work(&state->work);
+}
+
+static void debug_work(struct work_struct *work)
+{
+ struct fiq_debugger_state *state;
+ char work_cmd[DEBUG_MAX];
+ char *cmd;
+ unsigned long flags;
+
+ state = container_of(work, struct fiq_debugger_state, work);
+
+ spin_lock_irqsave(&state->work_lock, flags);
+
+ strlcpy(work_cmd, state->work_cmd, sizeof(work_cmd));
+ state->work_cmd[0] = '\0';
+
+ spin_unlock_irqrestore(&state->work_lock, flags);
+
+ cmd = work_cmd;
+ if (!strncmp(cmd, "reboot", 6)) {
+ cmd += 6;
+ while (*cmd == ' ')
+ cmd++;
+ if (cmd != '\0')
+ kernel_restart(cmd);
+ else
+ kernel_restart(NULL);
+ } else {
+ debug_printf(state, "unknown work command '%s'\n", work_cmd);
+ }
+}
+
+/* This function CANNOT be called in FIQ context */
+static void debug_irq_exec(struct fiq_debugger_state *state, char *cmd)
+{
+ if (!strcmp(cmd, "ps"))
+ do_ps(state);
+ if (!strcmp(cmd, "sysrq"))
+ do_sysrq(state, 'h');
+ if (!strncmp(cmd, "sysrq ", 6))
+ do_sysrq(state, cmd[6]);
+#ifdef CONFIG_KGDB
+ if (!strcmp(cmd, "kgdb"))
+ do_kgdb(state);
+#endif
+ if (!strncmp(cmd, "reboot", 6))
+ debug_schedule_work(state, cmd);
+}
+
+static void debug_help(struct fiq_debugger_state *state)
+{
+ debug_printf(state, "FIQ Debugger commands:\n"
+ " pc PC status\n"
+ " regs Register dump\n"
+ " allregs Extended Register dump\n"
+ " bt Stack trace\n"
+ " reboot [<c>] Reboot with command <c>\n"
+ " reset [<c>] Hard reset with command <c>\n"
+ " irqs Interupt status\n"
+ " kmsg Kernel log\n"
+ " version Kernel version\n");
+ debug_printf(state, " sleep Allow sleep while in FIQ\n"
+ " nosleep Disable sleep while in FIQ\n"
+ " console Switch terminal to console\n"
+ " cpu Current CPU\n"
+ " cpu <number> Switch to CPU<number>\n");
+ debug_printf(state, " ps Process list\n"
+ " sysrq sysrq options\n"
+ " sysrq <param> Execute sysrq with <param>\n");
+#ifdef CONFIG_KGDB
+ debug_printf(state, " kgdb Enter kernel debugger\n");
+#endif
+}
+
+static void take_affinity(void *info)
+{
+ struct fiq_debugger_state *state = info;
+ struct cpumask cpumask;
+
+ cpumask_clear(&cpumask);
+ cpumask_set_cpu(get_cpu(), &cpumask);
+
+ irq_set_affinity(state->uart_irq, &cpumask);
+}
+
+static void switch_cpu(struct fiq_debugger_state *state, int cpu)
+{
+ if (!debug_have_fiq(state))
+ smp_call_function_single(cpu, take_affinity, state, false);
+ state->current_cpu = cpu;
+}
+
+static bool debug_fiq_exec(struct fiq_debugger_state *state,
+ const char *cmd, unsigned *regs, void *svc_sp)
+{
+ bool signal_helper = false;
+
+ if (!strcmp(cmd, "help") || !strcmp(cmd, "?")) {
+ debug_help(state);
+ } else if (!strcmp(cmd, "pc")) {
+ debug_printf(state, " pc %08x cpsr %08x mode %s\n",
+ regs[15], regs[16], mode_name(regs[16]));
+ } else if (!strcmp(cmd, "regs")) {
+ dump_regs(state, regs);
+ } else if (!strcmp(cmd, "allregs")) {
+ dump_allregs(state, regs);
+ } else if (!strcmp(cmd, "bt")) {
+ dump_stacktrace(state, (struct pt_regs *)regs, 100, svc_sp);
+ } else if (!strncmp(cmd, "reset", 5)) {
+ cmd += 5;
+ while (*cmd == ' ')
+ cmd++;
+ if (*cmd) {
+ char tmp_cmd[32];
+ strlcpy(tmp_cmd, cmd, sizeof(tmp_cmd));
+ machine_restart(tmp_cmd);
+ } else {
+ machine_restart(NULL);
+ }
+ } else if (!strcmp(cmd, "irqs")) {
+ dump_irqs(state);
+ } else if (!strcmp(cmd, "kmsg")) {
+ dump_kernel_log(state);
+ } else if (!strcmp(cmd, "version")) {
+ debug_printf(state, "%s\n", linux_banner);
+ } else if (!strcmp(cmd, "sleep")) {
+ state->no_sleep = false;
+ debug_printf(state, "enabling sleep\n");
+ } else if (!strcmp(cmd, "nosleep")) {
+ state->no_sleep = true;
+ debug_printf(state, "disabling sleep\n");
+ } else if (!strcmp(cmd, "console")) {
+ debug_printf(state, "console mode\n");
+ debug_uart_flush(state);
+ state->console_enable = true;
+ } else if (!strcmp(cmd, "cpu")) {
+ debug_printf(state, "cpu %d\n", state->current_cpu);
+ } else if (!strncmp(cmd, "cpu ", 4)) {
+ unsigned long cpu = 0;
+ if (strict_strtoul(cmd + 4, 10, &cpu) == 0)
+ switch_cpu(state, cpu);
+ else
+ debug_printf(state, "invalid cpu\n");
+ debug_printf(state, "cpu %d\n", state->current_cpu);
+ } else {
+ if (state->debug_busy) {
+ debug_printf(state,
+ "command processor busy. trying to abort.\n");
+ state->debug_abort = -1;
+ } else {
+ strcpy(state->debug_cmd, cmd);
+ state->debug_busy = 1;
+ }
+
+ return true;
+ }
+ if (!state->console_enable)
+ debug_prompt(state);
+
+ return signal_helper;
+}
+
+static void sleep_timer_expired(unsigned long data)
+{
+ struct fiq_debugger_state *state = (struct fiq_debugger_state *)data;
+ unsigned long flags;
+
+ spin_lock_irqsave(&state->sleep_timer_lock, flags);
+ if (state->uart_enabled && !state->no_sleep) {
+ if (state->debug_enable && !state->console_enable) {
+ state->debug_enable = false;
+ debug_printf_nfiq(state, "suspending fiq debugger\n");
+ }
+ state->ignore_next_wakeup_irq = true;
+ debug_uart_disable(state);
+ state->uart_enabled = false;
+ enable_wakeup_irq(state);
+ }
+ wake_unlock(&state->debugger_wake_lock);
+ spin_unlock_irqrestore(&state->sleep_timer_lock, flags);
+}
+
+static void handle_wakeup(struct fiq_debugger_state *state)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&state->sleep_timer_lock, flags);
+ if (state->wakeup_irq >= 0 && state->ignore_next_wakeup_irq) {
+ state->ignore_next_wakeup_irq = false;
+ } else if (!state->uart_enabled) {
+ wake_lock(&state->debugger_wake_lock);
+ debug_uart_enable(state);
+ state->uart_enabled = true;
+ disable_wakeup_irq(state);
+ mod_timer(&state->sleep_timer, jiffies + HZ / 2);
+ }
+ spin_unlock_irqrestore(&state->sleep_timer_lock, flags);
+}
+
+static irqreturn_t wakeup_irq_handler(int irq, void *dev)
+{
+ struct fiq_debugger_state *state = dev;
+
+ if (!state->no_sleep)
+ debug_puts(state, "WAKEUP\n");
+ handle_wakeup(state);
+
+ return IRQ_HANDLED;
+}
+
+static void debug_handle_console_irq_context(struct fiq_debugger_state *state)
+{
+#if defined(CONFIG_FIQ_DEBUGGER_CONSOLE)
+ if (state->tty_port.ops) {
+ int i;
+ int count = fiq_debugger_ringbuf_level(state->tty_rbuf);
+ for (i = 0; i < count; i++) {
+ int c = fiq_debugger_ringbuf_peek(state->tty_rbuf, 0);
+ tty_insert_flip_char(&state->tty_port, c, TTY_NORMAL);
+ if (!fiq_debugger_ringbuf_consume(state->tty_rbuf, 1))
+ pr_warn("fiq tty failed to consume byte\n");
+ }
+ tty_flip_buffer_push(&state->tty_port);
+ }
+#endif
+}
+
+static void debug_handle_irq_context(struct fiq_debugger_state *state)
+{
+ if (!state->no_sleep) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&state->sleep_timer_lock, flags);
+ wake_lock(&state->debugger_wake_lock);
+ mod_timer(&state->sleep_timer, jiffies + HZ * 5);
+ spin_unlock_irqrestore(&state->sleep_timer_lock, flags);
+ }
+ debug_handle_console_irq_context(state);
+ if (state->debug_busy) {
+ debug_irq_exec(state, state->debug_cmd);
+ if (!state->console_enable)
+ debug_prompt(state);
+ state->debug_busy = 0;
+ }
+}
+
+static int debug_getc(struct fiq_debugger_state *state)
+{
+ return state->pdata->uart_getc(state->pdev);
+}
+
+static bool debug_handle_uart_interrupt(struct fiq_debugger_state *state,
+ int this_cpu, void *regs, void *svc_sp)
+{
+ int c;
+ static int last_c;
+ int count = 0;
+ bool signal_helper = false;
+
+ if (this_cpu != state->current_cpu) {
+ if (state->in_fiq)
+ return false;
+
+ if (atomic_inc_return(&state->unhandled_fiq_count) !=
+ MAX_UNHANDLED_FIQ_COUNT)
+ return false;
+
+ debug_printf(state, "fiq_debugger: cpu %d not responding, "
+ "reverting to cpu %d\n", state->current_cpu,
+ this_cpu);
+
+ atomic_set(&state->unhandled_fiq_count, 0);
+ switch_cpu(state, this_cpu);
+ return false;
+ }
+
+ state->in_fiq = true;
+
+ while ((c = debug_getc(state)) != FIQ_DEBUGGER_NO_CHAR) {
+ count++;
+ if (!state->debug_enable) {
+ if ((c == 13) || (c == 10)) {
+ state->debug_enable = true;
+ state->debug_count = 0;
+ debug_prompt(state);
+ }
+ } else if (c == FIQ_DEBUGGER_BREAK) {
+ state->console_enable = false;
+ debug_puts(state, "fiq debugger mode\n");
+ state->debug_count = 0;
+ debug_prompt(state);
+#ifdef CONFIG_FIQ_DEBUGGER_CONSOLE
+ } else if (state->console_enable && state->tty_rbuf) {
+ fiq_debugger_ringbuf_push(state->tty_rbuf, c);
+ signal_helper = true;
+#endif
+ } else if ((c >= ' ') && (c < 127)) {
+ if (state->debug_count < (DEBUG_MAX - 1)) {
+ state->debug_buf[state->debug_count++] = c;
+ debug_putc(state, c);
+ }
+ } else if ((c == 8) || (c == 127)) {
+ if (state->debug_count > 0) {
+ state->debug_count--;
+ debug_putc(state, 8);
+ debug_putc(state, ' ');
+ debug_putc(state, 8);
+ }
+ } else if ((c == 13) || (c == 10)) {
+ if (c == '\r' || (c == '\n' && last_c != '\r')) {
+ debug_putc(state, '\r');
+ debug_putc(state, '\n');
+ }
+ if (state->debug_count) {
+ state->debug_buf[state->debug_count] = 0;
+ state->debug_count = 0;
+ signal_helper |=
+ debug_fiq_exec(state, state->debug_buf,
+ regs, svc_sp);
+ } else {
+ debug_prompt(state);
+ }
+ }
+ last_c = c;
+ }
+ if (!state->console_enable)
+ debug_uart_flush(state);
+ if (state->pdata->fiq_ack)
+ state->pdata->fiq_ack(state->pdev, state->fiq);
+
+ /* poke sleep timer if necessary */
+ if (state->debug_enable && !state->no_sleep)
+ signal_helper = true;
+
+ atomic_set(&state->unhandled_fiq_count, 0);
+ state->in_fiq = false;
+
+ return signal_helper;
+}
+
+static void debug_fiq(struct fiq_glue_handler *h, void *regs, void *svc_sp)
+{
+ struct fiq_debugger_state *state =
+ container_of(h, struct fiq_debugger_state, handler);
+ unsigned int this_cpu = THREAD_INFO(svc_sp)->cpu;
+ bool need_irq;
+
+ need_irq = debug_handle_uart_interrupt(state, this_cpu, regs, svc_sp);
+ if (need_irq)
+ debug_force_irq(state);
+}
+
+/*
+ * When not using FIQs, we only use this single interrupt as an entry point.
+ * This just effectively takes over the UART interrupt and does all the work
+ * in this context.
+ */
+static irqreturn_t debug_uart_irq(int irq, void *dev)
+{
+ struct fiq_debugger_state *state = dev;
+ bool not_done;
+
+ handle_wakeup(state);
+
+ /* handle the debugger irq in regular context */
+ not_done = debug_handle_uart_interrupt(state, smp_processor_id(),
+ get_irq_regs(),
+ current_thread_info());
+ if (not_done)
+ debug_handle_irq_context(state);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * If FIQs are used, not everything can happen in fiq context.
+ * FIQ handler does what it can and then signals this interrupt to finish the
+ * job in irq context.
+ */
+static irqreturn_t debug_signal_irq(int irq, void *dev)
+{
+ struct fiq_debugger_state *state = dev;
+
+ if (state->pdata->force_irq_ack)
+ state->pdata->force_irq_ack(state->pdev, state->signal_irq);
+
+ debug_handle_irq_context(state);
+
+ return IRQ_HANDLED;
+}
+
+static void debug_resume(struct fiq_glue_handler *h)
+{
+ struct fiq_debugger_state *state =
+ container_of(h, struct fiq_debugger_state, handler);
+ if (state->pdata->uart_resume)
+ state->pdata->uart_resume(state->pdev);
+}
+
+#if defined(CONFIG_FIQ_DEBUGGER_CONSOLE)
+struct tty_driver *debug_console_device(struct console *co, int *index)
+{
+ *index = co->index;
+ return fiq_tty_driver;
+}
+
+static void debug_console_write(struct console *co,
+ const char *s, unsigned int count)
+{
+ struct fiq_debugger_state *state;
+ unsigned long flags;
+
+ state = container_of(co, struct fiq_debugger_state, console);
+
+ if (!state->console_enable && !state->syslog_dumping)
+ return;
+
+ debug_uart_enable(state);
+ spin_lock_irqsave(&state->console_lock, flags);
+ while (count--) {
+ if (*s == '\n')
+ debug_putc(state, '\r');
+ debug_putc(state, *s++);
+ }
+ debug_uart_flush(state);
+ spin_unlock_irqrestore(&state->console_lock, flags);
+ debug_uart_disable(state);
+}
+
+static struct console fiq_debugger_console = {
+ .name = "ttyFIQ",
+ .device = debug_console_device,
+ .write = debug_console_write,
+ .flags = CON_PRINTBUFFER | CON_ANYTIME | CON_ENABLED,
+};
+
+int fiq_tty_open(struct tty_struct *tty, struct file *filp)
+{
+ int line = tty->index;
+ struct fiq_debugger_state **states = tty->driver->driver_state;
+ struct fiq_debugger_state *state = states[line];
+
+ return tty_port_open(&state->tty_port, tty, filp);
+}
+
+void fiq_tty_close(struct tty_struct *tty, struct file *filp)
+{
+ tty_port_close(tty->port, tty, filp);
+}
+
+int fiq_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
+{
+ int i;
+ int line = tty->index;
+ struct fiq_debugger_state **states = tty->driver->driver_state;
+ struct fiq_debugger_state *state = states[line];
+
+ if (!state->console_enable)
+ return count;
+
+ debug_uart_enable(state);
+ spin_lock_irq(&state->console_lock);
+ for (i = 0; i < count; i++)
+ debug_putc(state, *buf++);
+ spin_unlock_irq(&state->console_lock);
+ debug_uart_disable(state);
+
+ return count;
+}
+
+int fiq_tty_write_room(struct tty_struct *tty)
+{
+ return 16;
+}
+
+#ifdef CONFIG_CONSOLE_POLL
+static int fiq_tty_poll_init(struct tty_driver *driver, int line, char *options)
+{
+ return 0;
+}
+
+static int fiq_tty_poll_get_char(struct tty_driver *driver, int line)
+{
+ struct fiq_debugger_state **states = driver->driver_state;
+ struct fiq_debugger_state *state = states[line];
+ int c = NO_POLL_CHAR;
+
+ debug_uart_enable(state);
+ if (debug_have_fiq(state)) {
+ int count = fiq_debugger_ringbuf_level(state->tty_rbuf);
+ if (count > 0) {
+ c = fiq_debugger_ringbuf_peek(state->tty_rbuf, 0);
+ fiq_debugger_ringbuf_consume(state->tty_rbuf, 1);
+ }
+ } else {
+ c = debug_getc(state);
+ if (c == FIQ_DEBUGGER_NO_CHAR)
+ c = NO_POLL_CHAR;
+ }
+ debug_uart_disable(state);
+
+ return c;
+}
+
+static void fiq_tty_poll_put_char(struct tty_driver *driver, int line, char ch)
+{
+ struct fiq_debugger_state **states = driver->driver_state;
+ struct fiq_debugger_state *state = states[line];
+ debug_uart_enable(state);
+ debug_putc(state, ch);
+ debug_uart_disable(state);
+}
+#endif
+
+static const struct tty_port_operations fiq_tty_port_ops;
+
+static const struct tty_operations fiq_tty_driver_ops = {
+ .write = fiq_tty_write,
+ .write_room = fiq_tty_write_room,
+ .open = fiq_tty_open,
+ .close = fiq_tty_close,
+#ifdef CONFIG_CONSOLE_POLL
+ .poll_init = fiq_tty_poll_init,
+ .poll_get_char = fiq_tty_poll_get_char,
+ .poll_put_char = fiq_tty_poll_put_char,
+#endif
+};
+
+static int fiq_debugger_tty_init(void)
+{
+ int ret;
+ struct fiq_debugger_state **states = NULL;
+
+ states = kzalloc(sizeof(*states) * MAX_FIQ_DEBUGGER_PORTS, GFP_KERNEL);
+ if (!states) {
+ pr_err("Failed to allocate fiq debugger state structres\n");
+ return -ENOMEM;
+ }
+
+ fiq_tty_driver = alloc_tty_driver(MAX_FIQ_DEBUGGER_PORTS);
+ if (!fiq_tty_driver) {
+ pr_err("Failed to allocate fiq debugger tty\n");
+ ret = -ENOMEM;
+ goto err_free_state;
+ }
+
+ fiq_tty_driver->owner = THIS_MODULE;
+ fiq_tty_driver->driver_name = "fiq-debugger";
+ fiq_tty_driver->name = "ttyFIQ";
+ fiq_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
+ fiq_tty_driver->subtype = SERIAL_TYPE_NORMAL;
+ fiq_tty_driver->init_termios = tty_std_termios;
+ fiq_tty_driver->flags = TTY_DRIVER_REAL_RAW |
+ TTY_DRIVER_DYNAMIC_DEV;
+ fiq_tty_driver->driver_state = states;
+
+ fiq_tty_driver->init_termios.c_cflag =
+ B115200 | CS8 | CREAD | HUPCL | CLOCAL;
+ fiq_tty_driver->init_termios.c_ispeed = 115200;
+ fiq_tty_driver->init_termios.c_ospeed = 115200;
+
+ tty_set_operations(fiq_tty_driver, &fiq_tty_driver_ops);
+
+ ret = tty_register_driver(fiq_tty_driver);
+ if (ret) {
+ pr_err("Failed to register fiq tty: %d\n", ret);
+ goto err_free_tty;
+ }
+
+ pr_info("Registered FIQ tty driver\n");
+ return 0;
+
+err_free_tty:
+ put_tty_driver(fiq_tty_driver);
+ fiq_tty_driver = NULL;
+err_free_state:
+ kfree(states);
+ return ret;
+}
+
+static int fiq_debugger_tty_init_one(struct fiq_debugger_state *state)
+{
+ int ret;
+ struct device *tty_dev;
+ struct fiq_debugger_state **states = fiq_tty_driver->driver_state;
+
+ states[state->pdev->id] = state;
+
+ state->tty_rbuf = fiq_debugger_ringbuf_alloc(1024);
+ if (!state->tty_rbuf) {
+ pr_err("Failed to allocate fiq debugger ringbuf\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ tty_port_init(&state->tty_port);
+ state->tty_port.ops = &fiq_tty_port_ops;
+
+ tty_dev = tty_port_register_device(&state->tty_port, fiq_tty_driver,
+ state->pdev->id, &state->pdev->dev);
+ if (IS_ERR(tty_dev)) {
+ pr_err("Failed to register fiq debugger tty device\n");
+ ret = PTR_ERR(tty_dev);
+ goto err;
+ }
+
+ device_set_wakeup_capable(tty_dev, 1);
+
+ pr_info("Registered fiq debugger ttyFIQ%d\n", state->pdev->id);
+
+ return 0;
+
+err:
+ fiq_debugger_ringbuf_free(state->tty_rbuf);
+ state->tty_rbuf = NULL;
+ return ret;
+}
+#endif
+
+static int fiq_debugger_dev_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct fiq_debugger_state *state = platform_get_drvdata(pdev);
+
+ if (state->pdata->uart_dev_suspend)
+ return state->pdata->uart_dev_suspend(pdev);
+ return 0;
+}
+
+static int fiq_debugger_dev_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct fiq_debugger_state *state = platform_get_drvdata(pdev);
+
+ if (state->pdata->uart_dev_resume)
+ return state->pdata->uart_dev_resume(pdev);
+ return 0;
+}
+
+static int fiq_debugger_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct fiq_debugger_pdata *pdata = dev_get_platdata(&pdev->dev);
+ struct fiq_debugger_state *state;
+ int fiq;
+ int uart_irq;
+
+ if (pdev->id >= MAX_FIQ_DEBUGGER_PORTS)
+ return -EINVAL;
+
+ if (!pdata->uart_getc || !pdata->uart_putc)
+ return -EINVAL;
+ if ((pdata->uart_enable && !pdata->uart_disable) ||
+ (!pdata->uart_enable && pdata->uart_disable))
+ return -EINVAL;
+
+ fiq = platform_get_irq_byname(pdev, "fiq");
+ uart_irq = platform_get_irq_byname(pdev, "uart_irq");
+
+ /* uart_irq mode and fiq mode are mutually exclusive, but one of them
+ * is required */
+ if ((uart_irq < 0 && fiq < 0) || (uart_irq >= 0 && fiq >= 0))
+ return -EINVAL;
+ if (fiq >= 0 && !pdata->fiq_enable)
+ return -EINVAL;
+
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
+ setup_timer(&state->sleep_timer, sleep_timer_expired,
+ (unsigned long)state);
+ state->pdata = pdata;
+ state->pdev = pdev;
+ state->no_sleep = initial_no_sleep;
+ state->debug_enable = initial_debug_enable;
+ state->console_enable = initial_console_enable;
+
+ state->fiq = fiq;
+ state->uart_irq = uart_irq;
+ state->signal_irq = platform_get_irq_byname(pdev, "signal");
+ state->wakeup_irq = platform_get_irq_byname(pdev, "wakeup");
+
+ INIT_WORK(&state->work, debug_work);
+ spin_lock_init(&state->work_lock);
+
+ platform_set_drvdata(pdev, state);
+
+ spin_lock_init(&state->sleep_timer_lock);
+
+ if (state->wakeup_irq < 0 && debug_have_fiq(state))
+ state->no_sleep = true;
+ state->ignore_next_wakeup_irq = !state->no_sleep;
+
+ wake_lock_init(&state->debugger_wake_lock,
+ WAKE_LOCK_SUSPEND, "serial-debug");
+
+ state->clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(state->clk))
+ state->clk = NULL;
+
+ /* do not call pdata->uart_enable here since uart_init may still
+ * need to do some initialization before uart_enable can work.
+ * So, only try to manage the clock during init.
+ */
+ if (state->clk)
+ clk_enable(state->clk);
+
+ if (pdata->uart_init) {
+ ret = pdata->uart_init(pdev);
+ if (ret)
+ goto err_uart_init;
+ }
+
+ debug_printf_nfiq(state, "<hit enter %sto activate fiq debugger>\n",
+ state->no_sleep ? "" : "twice ");
+
+ if (debug_have_fiq(state)) {
+ state->handler.fiq = debug_fiq;
+ state->handler.resume = debug_resume;
+ ret = fiq_glue_register_handler(&state->handler);
+ if (ret) {
+ pr_err("%s: could not install fiq handler\n", __func__);
+ goto err_register_fiq;
+ }
+
+ pdata->fiq_enable(pdev, state->fiq, 1);
+ } else {
+ ret = request_irq(state->uart_irq, debug_uart_irq,
+ IRQF_NO_SUSPEND, "debug", state);
+ if (ret) {
+ pr_err("%s: could not install irq handler\n", __func__);
+ goto err_register_irq;
+ }
+
+ /* for irq-only mode, we want this irq to wake us up, if it
+ * can.
+ */
+ enable_irq_wake(state->uart_irq);
+ }
+
+ if (state->clk)
+ clk_disable(state->clk);
+
+ if (state->signal_irq >= 0) {
+ ret = request_irq(state->signal_irq, debug_signal_irq,
+ IRQF_TRIGGER_RISING, "debug-signal", state);
+ if (ret)
+ pr_err("serial_debugger: could not install signal_irq");
+ }
+
+ if (state->wakeup_irq >= 0) {
+ ret = request_irq(state->wakeup_irq, wakeup_irq_handler,
+ IRQF_TRIGGER_FALLING | IRQF_DISABLED,
+ "debug-wakeup", state);
+ if (ret) {
+ pr_err("serial_debugger: "
+ "could not install wakeup irq\n");
+ state->wakeup_irq = -1;
+ } else {
+ ret = enable_irq_wake(state->wakeup_irq);
+ if (ret) {
+ pr_err("serial_debugger: "
+ "could not enable wakeup\n");
+ state->wakeup_irq_no_set_wake = true;
+ }
+ }
+ }
+ if (state->no_sleep)
+ handle_wakeup(state);
+
+#if defined(CONFIG_FIQ_DEBUGGER_CONSOLE)
+ spin_lock_init(&state->console_lock);
+ state->console = fiq_debugger_console;
+ state->console.index = pdev->id;
+ if (!console_set_on_cmdline)
+ add_preferred_console(state->console.name,
+ state->console.index, NULL);
+ register_console(&state->console);
+ fiq_debugger_tty_init_one(state);
+#endif
+ return 0;
+
+err_register_irq:
+err_register_fiq:
+ if (pdata->uart_free)
+ pdata->uart_free(pdev);
+err_uart_init:
+ if (state->clk)
+ clk_disable(state->clk);
+ if (state->clk)
+ clk_put(state->clk);
+ wake_lock_destroy(&state->debugger_wake_lock);
+ platform_set_drvdata(pdev, NULL);
+ kfree(state);
+ return ret;
+}
+
+static const struct dev_pm_ops fiq_debugger_dev_pm_ops = {
+ .suspend = fiq_debugger_dev_suspend,
+ .resume = fiq_debugger_dev_resume,
+};
+
+static struct platform_driver fiq_debugger_driver = {
+ .probe = fiq_debugger_probe,
+ .driver = {
+ .name = "fiq_debugger",
+ .pm = &fiq_debugger_dev_pm_ops,
+ },
+};
+
+static int __init fiq_debugger_init(void)
+{
+#if defined(CONFIG_FIQ_DEBUGGER_CONSOLE)
+ fiq_debugger_tty_init();
+#endif
+ return platform_driver_register(&fiq_debugger_driver);
+}
+
+postcore_initcall(fiq_debugger_init);
diff --git a/arch/arm/common/fiq_debugger_ringbuf.h b/arch/arm/common/fiq_debugger_ringbuf.h
new file mode 100644
index 00000000000..2649b558108
--- /dev/null
+++ b/arch/arm/common/fiq_debugger_ringbuf.h
@@ -0,0 +1,94 @@
+/*
+ * arch/arm/common/fiq_debugger_ringbuf.c
+ *
+ * simple lockless ringbuffer
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
+struct fiq_debugger_ringbuf {
+ int len;
+ int head;
+ int tail;
+ u8 buf[];
+};
+
+
+static inline struct fiq_debugger_ringbuf *fiq_debugger_ringbuf_alloc(int len)
+{
+ struct fiq_debugger_ringbuf *rbuf;
+
+ rbuf = kzalloc(sizeof(*rbuf) + len, GFP_KERNEL);
+ if (rbuf == NULL)
+ return NULL;
+
+ rbuf->len = len;
+ rbuf->head = 0;
+ rbuf->tail = 0;
+ smp_mb();
+
+ return rbuf;
+}
+
+static inline void fiq_debugger_ringbuf_free(struct fiq_debugger_ringbuf *rbuf)
+{
+ kfree(rbuf);
+}
+
+static inline int fiq_debugger_ringbuf_level(struct fiq_debugger_ringbuf *rbuf)
+{
+ int level = rbuf->head - rbuf->tail;
+
+ if (level < 0)
+ level = rbuf->len + level;
+
+ return level;
+}
+
+static inline int fiq_debugger_ringbuf_room(struct fiq_debugger_ringbuf *rbuf)
+{
+ return rbuf->len - fiq_debugger_ringbuf_level(rbuf) - 1;
+}
+
+static inline u8
+fiq_debugger_ringbuf_peek(struct fiq_debugger_ringbuf *rbuf, int i)
+{
+ return rbuf->buf[(rbuf->tail + i) % rbuf->len];
+}
+
+static inline int
+fiq_debugger_ringbuf_consume(struct fiq_debugger_ringbuf *rbuf, int count)
+{
+ count = min(count, fiq_debugger_ringbuf_level(rbuf));
+
+ rbuf->tail = (rbuf->tail + count) % rbuf->len;
+ smp_mb();
+
+ return count;
+}
+
+static inline int
+fiq_debugger_ringbuf_push(struct fiq_debugger_ringbuf *rbuf, u8 datum)
+{
+ if (fiq_debugger_ringbuf_room(rbuf) == 0)
+ return 0;
+
+ rbuf->buf[rbuf->head] = datum;
+ smp_mb();
+ rbuf->head = (rbuf->head + 1) % rbuf->len;
+ smp_mb();
+
+ return 1;
+}
diff --git a/arch/arm/configs/athene_defconfig b/arch/arm/configs/athene_defconfig
index 48d0616a2cc..4ad2df4d640 100644
--- a/arch/arm/configs/athene_defconfig
+++ b/arch/arm/configs/athene_defconfig
@@ -1,7 +1,6 @@
-
#
# Automatically generated file; DO NOT EDIT.
-# Linux/arm 3.10.104 Kernel Configuration
+# Linux/arm 3.10.107 Kernel Configuration
#
CONFIG_ARM=y
CONFIG_ARM_HAS_SG_CHAIN=y
@@ -105,6 +104,8 @@ CONFIG_RCU_FANOUT_LEAF=16
CONFIG_RCU_FAST_NO_HZ=y
# CONFIG_TREE_RCU_TRACE is not set
CONFIG_RCU_BOOST=y
+CONFIG_RCU_BOOST_PRIO=1
+CONFIG_RCU_BOOST_DELAY=500
# CONFIG_RCU_NOCB_CPU is not set
CONFIG_IKCONFIG=y
# CONFIG_IKCONFIG_PROC is not set
@@ -272,8 +273,8 @@ CONFIG_CGROUP_BFQIO=y
# CONFIG_DEFAULT_DEADLINE is not set
# CONFIG_DEFAULT_ROW is not set
CONFIG_DEFAULT_CFQ=y
-# CONFIG_DEFAULT_NOOP is not set
# CONFIG_DEFAULT_BFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
CONFIG_ASN1=y
CONFIG_UNINLINE_SPIN_UNLOCK=y
@@ -448,6 +449,7 @@ CONFIG_MULTI_IRQ_HANDLER=y
# CONFIG_ARM_ERRATA_764369 is not set
# CONFIG_ARM_ERRATA_775420 is not set
# CONFIG_ARM_ERRATA_798181 is not set
+# CONFIG_FIQ_DEBUGGER is not set
#
# Bus support
@@ -639,7 +641,6 @@ CONFIG_PM=y
CONFIG_ARCH_HAS_OPP=y
CONFIG_PM_OPP=y
CONFIG_PM_CLK=y
-CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
CONFIG_CPU_PM=y
CONFIG_SUSPEND_TIME=y
CONFIG_SUSPEND_TIME_TIMEKEEPING=y
@@ -882,7 +883,6 @@ CONFIG_IP_NF_MATCH_RPFILTER=y
CONFIG_IP_NF_MATCH_TTL=y
CONFIG_IP_NF_FILTER=y
CONFIG_IP_NF_TARGET_REJECT=y
-# CONFIG_IP_NF_TARGET_REJECT_SKERR is not set
# CONFIG_IP_NF_TARGET_ULOG is not set
CONFIG_NF_NAT_IPV4=y
CONFIG_IP_NF_TARGET_MASQUERADE=y
@@ -920,7 +920,6 @@ CONFIG_IP6_NF_MATCH_RPFILTER=y
# CONFIG_IP6_NF_TARGET_HL is not set
CONFIG_IP6_NF_FILTER=y
CONFIG_IP6_NF_TARGET_REJECT=y
-# CONFIG_IP6_NF_TARGET_REJECT_SKERR is not set
CONFIG_IP6_NF_MANGLE=y
CONFIG_IP6_NF_RAW=y
# CONFIG_IP6_NF_SECURITY is not set
@@ -1234,7 +1233,7 @@ CONFIG_USB_EXT_TYPE_C_PERICOM=y
CONFIG_USB_EXT_TYPE_C_TI=y
# CONFIG_TI_DRV2667 is not set
# CONFIG_QCOM_LIQUID_DOCK is not set
-CONFIG_UID_CPUTIME=y
+CONFIG_UID_SYS_STATS=y
CONFIG_DROPBOX=y
CONFIG_ALSA_TO_H2W=y
# CONFIG_C2PORT is not set
@@ -1336,6 +1335,8 @@ CONFIG_DM_REQ_CRYPT=y
# CONFIG_DM_FLAKEY is not set
CONFIG_DM_VERITY=y
# CONFIG_DM_VERITY_FEC is not set
+# CONFIG_DM_VERITY_HASH_PREFETCH_MIN_SIZE_128 is not set
+CONFIG_DM_VERITY_HASH_PREFETCH_MIN_SIZE=1
# CONFIG_DM_ANDROID_VERITY is not set
# CONFIG_TARGET_CORE is not set
CONFIG_NETDEVICES=y
@@ -1641,7 +1642,6 @@ CONFIG_INPUT_TOUCHSCREEN=y
# CONFIG_TOUCHSCREEN_ST1232 is not set
# CONFIG_TOUCHSCREEN_TPS6507X is not set
# CONFIG_TOUCHSCREEN_FT5X06 is not set
-# CONFIG_TOUCHSCREEN_MSTAR21XX is not set
CONFIG_TOUCHSCREEN_GEN_VKEYS=y
# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set
# CONFIG_TOUCHSCREEN_GT9XX is not set
@@ -1656,7 +1656,7 @@ CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_MMI=y
CONFIG_INPUT_MISC=y
# CONFIG_INPUT_AD714X is not set
# CONFIG_INPUT_BMA150 is not set
-# CONFIG_INPUT_HBTP_INPUT is not set
+CONFIG_INPUT_HBTP_INPUT=y
# CONFIG_INPUT_MMA8450 is not set
# CONFIG_INPUT_MPU3050 is not set
# CONFIG_SENSORS_MPU6050 is not set
@@ -1775,10 +1775,10 @@ CONFIG_HW_RANDOM=y
# CONFIG_HW_RANDOM_ATMEL is not set
# CONFIG_HW_RANDOM_EXYNOS is not set
CONFIG_HW_RANDOM_MSM=y
-# CONFIG_DEVPORT is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
+# CONFIG_DCC_TTY is not set
CONFIG_MSM_SMD_PKT=y
CONFIG_MSM_ADSPRPC=y
# CONFIG_MSM_RDBG is not set
@@ -1854,6 +1854,7 @@ CONFIG_SPMI=y
CONFIG_SPMI_MSM_PMIC_ARB=y
# CONFIG_SPMI_MSM_PMIC_ARB_PANIC_ON_SPURIOUS_IRQ is not set
CONFIG_MSM_QPNP_INT=y
+# CONFIG_MSM_SPMI_DEBUGFS_RO is not set
#
# Qualcomm MSM SSBI bus support
@@ -3160,7 +3161,6 @@ CONFIG_ION=y
# CONFIG_ION_TEST is not set
CONFIG_ION_MSM=y
# CONFIG_ALLOC_BUFFERS_IN_4K_CHUNKS is not set
-# CONFIG_FIQ_DEBUGGER is not set
# CONFIG_FIQ_WATCHDOG is not set
# CONFIG_USB_WPAN_HCD is not set
# CONFIG_WIMAX_GDM72XX is not set
@@ -3414,6 +3414,7 @@ CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT4_FS=y
# CONFIG_EXT4_FS_POSIX_ACL is not set
CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_EXT4_FS_ENCRYPTION is not set
# CONFIG_EXT4_DEBUG is not set
CONFIG_F2FS_FS=y
CONFIG_F2FS_STAT_FS=y
@@ -3442,12 +3443,15 @@ CONFIG_DNOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_FANOTIFY is not set
CONFIG_QUOTA=y
-# CONFIG_PRINT_QUOTA_WARNING is not set0
-# CONFIG_QUOTACTL is not set
+# CONFIG_QUOTA_NETLINK_INTERFACE is not set
+# CONFIG_PRINT_QUOTA_WARNING is not set
+# CONFIG_QUOTA_DEBUG is not set
+# CONFIG_QFMT_V1 is not set
+# CONFIG_QFMT_V2 is not set
+CONFIG_QUOTACTL=y
# CONFIG_AUTOFS4_FS is not set
CONFIG_FUSE_FS=y
# CONFIG_CUSE is not set
-CONFIG_ADRENO_IDLER=y
#
# Caches
diff --git a/arch/arm/include/asm/fiq_debugger.h b/arch/arm/include/asm/fiq_debugger.h
new file mode 100644
index 00000000000..4d274883ba6
--- /dev/null
+++ b/arch/arm/include/asm/fiq_debugger.h
@@ -0,0 +1,64 @@
+/*
+ * arch/arm/include/asm/fiq_debugger.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ * Author: Colin Cross <ccross@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#ifndef _ARCH_ARM_MACH_TEGRA_FIQ_DEBUGGER_H_
+#define _ARCH_ARM_MACH_TEGRA_FIQ_DEBUGGER_H_
+
+#include <linux/serial_core.h>
+
+#define FIQ_DEBUGGER_NO_CHAR NO_POLL_CHAR
+#define FIQ_DEBUGGER_BREAK 0x00ff0100
+
+#define FIQ_DEBUGGER_FIQ_IRQ_NAME "fiq"
+#define FIQ_DEBUGGER_SIGNAL_IRQ_NAME "signal"
+#define FIQ_DEBUGGER_WAKEUP_IRQ_NAME "wakeup"
+
+/**
+ * struct fiq_debugger_pdata - fiq debugger platform data
+ * @uart_resume: used to restore uart state right before enabling
+ * the fiq.
+ * @uart_enable: Do the work necessary to communicate with the uart
+ * hw (enable clocks, etc.). This must be ref-counted.
+ * @uart_disable: Do the work necessary to disable the uart hw
+ * (disable clocks, etc.). This must be ref-counted.
+ * @uart_dev_suspend: called during PM suspend, generally not needed
+ * for real fiq mode debugger.
+ * @uart_dev_resume: called during PM resume, generally not needed
+ * for real fiq mode debugger.
+ */
+struct fiq_debugger_pdata {
+ int (*uart_init)(struct platform_device *pdev);
+ void (*uart_free)(struct platform_device *pdev);
+ int (*uart_resume)(struct platform_device *pdev);
+ int (*uart_getc)(struct platform_device *pdev);
+ void (*uart_putc)(struct platform_device *pdev, unsigned int c);
+ void (*uart_flush)(struct platform_device *pdev);
+ void (*uart_enable)(struct platform_device *pdev);
+ void (*uart_disable)(struct platform_device *pdev);
+
+ int (*uart_dev_suspend)(struct platform_device *pdev);
+ int (*uart_dev_resume)(struct platform_device *pdev);
+
+ void (*fiq_enable)(struct platform_device *pdev, unsigned int fiq,
+ bool enable);
+ void (*fiq_ack)(struct platform_device *pdev, unsigned int fiq);
+
+ void (*force_irq)(struct platform_device *pdev, unsigned int irq);
+ void (*force_irq_ack)(struct platform_device *pdev, unsigned int irq);
+};
+
+#endif
diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h
index 943504f53f5..eeb40452d6d 100644
--- a/arch/arm/include/asm/pgalloc.h
+++ b/arch/arm/include/asm/pgalloc.h
@@ -155,7 +155,15 @@ pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
static inline void
pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep)
{
- __pmd_populate(pmdp, page_to_phys(ptep), _PAGE_USER_TABLE);
+ extern pmdval_t user_pmd_table;
+ pmdval_t prot;
+
+ if (__LINUX_ARM_ARCH__ >= 6 && !IS_ENABLED(CONFIG_ARM_LPAE))
+ prot = user_pmd_table;
+ else
+ prot = _PAGE_USER_TABLE;
+
+ __pmd_populate(pmdp, page_to_phys(ptep), prot);
}
#define pmd_pgtable(pmd) pmd_page(pmd)
diff --git a/arch/arm/include/asm/pgtable-2level-hwdef.h b/arch/arm/include/asm/pgtable-2level-hwdef.h
index 5cfba15cb40..5e68278e953 100644
--- a/arch/arm/include/asm/pgtable-2level-hwdef.h
+++ b/arch/arm/include/asm/pgtable-2level-hwdef.h
@@ -20,12 +20,14 @@
#define PMD_TYPE_FAULT (_AT(pmdval_t, 0) << 0)
#define PMD_TYPE_TABLE (_AT(pmdval_t, 1) << 0)
#define PMD_TYPE_SECT (_AT(pmdval_t, 2) << 0)
+#define PMD_PXNTABLE (_AT(pmdval_t, 1) << 2) /* v7 */
#define PMD_BIT4 (_AT(pmdval_t, 1) << 4)
#define PMD_DOMAIN(x) (_AT(pmdval_t, (x)) << 5)
#define PMD_PROTECTION (_AT(pmdval_t, 1) << 9) /* v5 */
/*
* - section
*/
+#define PMD_SECT_PXN (_AT(pmdval_t, 1) << 0) /* v7 */
#define PMD_SECT_BUFFERABLE (_AT(pmdval_t, 1) << 2)
#define PMD_SECT_CACHEABLE (_AT(pmdval_t, 1) << 3)
#define PMD_SECT_XN (_AT(pmdval_t, 1) << 4) /* v6 */
diff --git a/arch/arm/include/asm/pgtable-3level-hwdef.h b/arch/arm/include/asm/pgtable-3level-hwdef.h
index e0fab5b2f01..043bc389f38 100644
--- a/arch/arm/include/asm/pgtable-3level-hwdef.h
+++ b/arch/arm/include/asm/pgtable-3level-hwdef.h
@@ -75,6 +75,7 @@
#define PTE_EXT_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */
#define PTE_EXT_AF (_AT(pteval_t, 1) << 10) /* Access Flag */
#define PTE_EXT_NG (_AT(pteval_t, 1) << 11) /* nG */
+#define PTE_EXT_PXN (_AT(pteval_t, 1) << 53) /* PXN */
#define PTE_EXT_XN (_AT(pteval_t, 1) << 54) /* XN */
/*
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index 6b103894f8e..f25b6119e02 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -31,7 +31,6 @@
#include <mach/hardware.h>
#include <mach/irqs.h>
-#include <mach/reset.h>
#include "generic.h"
@@ -135,7 +134,6 @@ static void sa1100_power_off(void)
void sa11x0_restart(enum reboot_mode mode, const char *cmd)
{
- clear_reset_status(RESET_STATUS_ALL);
if (mode == REBOOT_SOFT) {
/* Jump into ROM at address 0 */
soft_restart(0);
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 1e1f4f45174..83434b993f6 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -51,6 +51,8 @@ EXPORT_SYMBOL(empty_zero_page);
*/
pmd_t *top_pmd;
+pmdval_t user_pmd_table = _PAGE_USER_TABLE;
+
#define CPOLICY_UNCACHED 0
#define CPOLICY_BUFFERED 1
#define CPOLICY_WRITETHROUGH 2
@@ -543,6 +545,25 @@ static void __init build_mem_type_table(void)
s2_pgprot = cp->pte_s2;
hyp_device_pgprot = s2_device_pgprot = mem_types[MT_DEVICE].prot_pte;
+#ifndef CONFIG_ARM_LPAE
+ /*
+ * We don't use domains on ARMv6 (since this causes problems with
+ * v6/v7 kernels), so we must use a separate memory type for user
+ * r/o, kernel r/w to map the vectors page.
+ */
+ if (cpu_arch == CPU_ARCH_ARMv6)
+ vecs_pgprot |= L_PTE_MT_VECTORS;
+
+ /*
+ * Check is it with support for the PXN bit
+ * in the Short-descriptor translation table format descriptors.
+ */
+ if (cpu_arch == CPU_ARCH_ARMv7 &&
+ (read_cpuid_ext(CPUID_EXT_MMFR0) & 0xF) >= 4) {
+ user_pmd_table |= PMD_PXNTABLE;
+ }
+#endif
+
/*
* We don't use domains on ARMv6 (since this causes problems with
* v6/v7 kernels), so we must use a separate memory type for user
@@ -622,6 +643,11 @@ static void __init build_mem_type_table(void)
}
kern_pgprot |= PTE_EXT_AF;
vecs_pgprot |= PTE_EXT_AF;
+
+ /*
+ * Set PXN for user mappings
+ */
+ user_pgprot |= PTE_EXT_PXN;
#endif
for (i = 0; i < 16; i++) {
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 2dba280f6b3..9d49bea25a6 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -37,6 +37,7 @@ config ARM64
select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
select HAVE_ARCH_SECCOMP_FILTER
select HAVE_ARCH_AUDITSYSCALL
+ select HAVE_ARCH_SECCOMP_FILTER
select HAVE_ARCH_TRACEHOOK
select HAVE_C_RECORDMCOUNT
select HAVE_CC_STACKPROTECTOR
@@ -586,6 +587,20 @@ config SECCOMP
defined by each seccomp mode.
+config SECCOMP
+ bool "Enable seccomp to safely compute untrusted bytecode"
+ ---help---
+ This kernel feature is useful for number crunching applications
+ that may need to compute untrusted bytecode during their
+ execution. By using pipes or other transports made available to
+ the process as file descriptors supporting the read/write
+ syscalls, it's possible to isolate those applications in
+ their own address space using seccomp. Once seccomp is
+ enabled via prctl(PR_SET_SECCOMP), it cannot be disabled
+ and the task is only allowed to execute a few safe syscalls
+ defined by each seccomp mode.
+
+
endmenu
menu "Boot options"
diff --git a/arch/arm64/include/uapi/asm/ptrace.h b/arch/arm64/include/uapi/asm/ptrace.h
index c136fd53c84..164e2bbe9af 100644
--- a/arch/arm64/include/uapi/asm/ptrace.h
+++ b/arch/arm64/include/uapi/asm/ptrace.h
@@ -23,6 +23,7 @@
#include <asm/hwcap.h>
+#define PTRACE_SET_SYSCALL 23
/*
* PSR bits
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 17b99ae8dbd..6db6c3b56a3 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -507,7 +507,7 @@ el0_inv:
mov x0, sp
mov x1, #BAD_SYNC
mrs x2, esr_el1
- b bad_el0_sync
+ b bad_mode
ENDPROC(el0_sync)
.align 6
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index b907a6d0ac1..b46415dfb5e 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -164,6 +164,7 @@ static int fpsimd_cpu_pm_notifier(struct notifier_block *self,
case CPU_PM_ENTER:
if (current->mm)
fpsimd_save_state(&current->thread.fpsimd_state);
+ this_cpu_write(fpsimd_last_state, NULL);
break;
case CPU_PM_EXIT:
if (current->mm)
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index dbb52c0dad5..cbd09984e1a 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -707,8 +707,10 @@ static int compat_gpr_get(struct task_struct *target,
kbuf += sizeof(reg);
} else {
ret = copy_to_user(ubuf, &reg, sizeof(reg));
- if (ret)
+ if (ret) {
+ ret = -EFAULT;
break;
+ }
ubuf += sizeof(reg);
}
@@ -746,8 +748,10 @@ static int compat_gpr_set(struct task_struct *target,
kbuf += sizeof(reg);
} else {
ret = copy_from_user(&reg, ubuf, sizeof(reg));
- if (ret)
- return ret;
+ if (ret) {
+ ret = -EFAULT;
+ break;
+ }
ubuf += sizeof(reg);
}
@@ -1121,7 +1125,19 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
long arch_ptrace(struct task_struct *child, long request,
unsigned long addr, unsigned long data)
{
- return ptrace_request(child, request, addr, data);
+ int ret;
+
+ switch (request) {
+ case PTRACE_SET_SYSCALL:
+ task_pt_regs(child)->syscallno = data;
+ ret = 0;
+ break;
+ default:
+ ret = ptrace_request(child, request, addr, data);
+ break;
+ }
+
+ return ret;
}
enum ptrace_syscall_dir {
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 207e11ad5fe..0ff794a482d 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -499,7 +499,11 @@ static int c_show(struct seq_file *m, void *v)
#endif
seq_printf(m, "\nCPU implementer\t: 0x%02x\n", read_cpuid_id() >> 24);
- seq_printf(m, "CPU architecture: 8\n");
+ seq_printf(m, "CPU architecture: %s\n",
+#if IS_ENABLED(CONFIG_ARMV7_COMPAT_CPUINFO)
+ is_compat_task() ? "8" :
+#endif
+ "AArch64");
seq_printf(m, "CPU variant\t: 0x%x\n", (read_cpuid_id() >> 20) & 15);
seq_printf(m, "CPU part\t: 0x%03x\n", (read_cpuid_id() >> 4) & 0xfff);
seq_printf(m, "CPU revision\t: %d\n", read_cpuid_id() & 15);
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 0e1447cbadd..2198961ebad 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -406,33 +406,16 @@ asmlinkage long do_ni_syscall(struct pt_regs *regs)
}
/*
- * bad_mode handles the impossible case in the exception vector. This is always
- * fatal.
+ * bad_mode handles the impossible case in the exception vector.
*/
asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr)
{
- console_verbose();
-
- pr_crit("Bad mode in %s handler detected, code 0x%08x\n",
- handler[reason], esr);
-
- die("Oops - bad mode", regs, 0);
- local_irq_disable();
- panic("bad mode");
-}
-
-/*
- * bad_el0_sync handles unexpected, but potentially recoverable synchronous
- * exceptions taken from EL0. Unlike bad_mode, this returns.
- */
-asmlinkage void bad_el0_sync(struct pt_regs *regs, int reason, unsigned int esr)
-{
siginfo_t info;
void __user *pc = (void __user *)instruction_pointer(regs);
console_verbose();
- pr_crit("Bad EL0 synchronous exception detected on CPU%d, code 0x%08x\n",
- smp_processor_id(), esr);
+ pr_crit("Bad mode in %s handler detected, code 0x%08x\n",
+ handler[reason], esr);
__show_regs(regs);
info.si_signo = SIGILL;
@@ -446,7 +429,7 @@ asmlinkage void bad_el0_sync(struct pt_regs *regs, int reason, unsigned int esr)
arm64_check_cache_ecc(NULL);
}
- force_sig_info(info.si_signo, &info, current);
+ arm64_notify_die("Oops - bad mode", regs, &info, 0);
}
void __pte_error(const char *file, int line, unsigned long val)
diff --git a/arch/arm64/kernel/vdso/vdso.S b/arch/arm64/kernel/vdso/vdso.S
index 60c1db54b41..82379a70ef0 100644
--- a/arch/arm64/kernel/vdso/vdso.S
+++ b/arch/arm64/kernel/vdso/vdso.S
@@ -21,9 +21,8 @@
#include <linux/const.h>
#include <asm/page.h>
- __PAGE_ALIGNED_DATA
-
.globl vdso_start, vdso_end
+ .section .rodata
.balign PAGE_SIZE
vdso_start:
.incbin "arch/arm64/kernel/vdso/vdso.so"
diff --git a/arch/mips/include/asm/branch.h b/arch/mips/include/asm/branch.h
index e28a3e0eb3c..582d8b61ce5 100644
--- a/arch/mips/include/asm/branch.h
+++ b/arch/mips/include/asm/branch.h
@@ -44,10 +44,7 @@ static inline int compute_return_epc(struct pt_regs *regs)
return __microMIPS_compute_return_epc(regs);
if (cpu_has_mips16)
return __MIPS16e_compute_return_epc(regs);
- return regs->cp0_epc;
- }
-
- if (!delay_slot(regs)) {
+ } else if (!delay_slot(regs)) {
regs->cp0_epc += 4;
return 0;
}
diff --git a/arch/mips/include/uapi/asm/unistd.h b/arch/mips/include/uapi/asm/unistd.h
index 1dee279f966..af4d5c0a2f0 100644
--- a/arch/mips/include/uapi/asm/unistd.h
+++ b/arch/mips/include/uapi/asm/unistd.h
@@ -369,16 +369,22 @@
#define __NR_process_vm_writev (__NR_Linux + 346)
#define __NR_kcmp (__NR_Linux + 347)
#define __NR_finit_module (__NR_Linux + 348)
+/* Backporting seccomp, skip a few ...
+ * #define __NR_sched_setattr (__NR_Linux + 349)
+ * #define __NR_sched_getattr (__NR_Linux + 350)
+ * #define __NR_renameat2 (__NR_Linux + 351)
+ */
+#define __NR_seccomp (__NR_Linux + 352)
/*
* Offset of the last Linux o32 flavoured syscall
*/
-#define __NR_Linux_syscalls 348
+#define __NR_Linux_syscalls 352
#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
#define __NR_O32_Linux 4000
-#define __NR_O32_Linux_syscalls 348
+#define __NR_O32_Linux_syscalls 352
#if _MIPS_SIM == _MIPS_SIM_ABI64
@@ -695,16 +701,22 @@
#define __NR_kcmp (__NR_Linux + 306)
#define __NR_finit_module (__NR_Linux + 307)
#define __NR_getdents64 (__NR_Linux + 308)
+/* Backporting seccomp, skip a few ...
+ * #define __NR_sched_setattr (__NR_Linux + 309)
+ * #define __NR_sched_getattr (__NR_Linux + 310)
+ * #define __NR_renameat2 (__NR_Linux + 311)
+ */
+#define __NR_seccomp (__NR_Linux + 312)
/*
* Offset of the last Linux 64-bit flavoured syscall
*/
-#define __NR_Linux_syscalls 308
+#define __NR_Linux_syscalls 312
#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
#define __NR_64_Linux 5000
-#define __NR_64_Linux_syscalls 308
+#define __NR_64_Linux_syscalls 312
#if _MIPS_SIM == _MIPS_SIM_NABI32
@@ -1025,15 +1037,21 @@
#define __NR_process_vm_writev (__NR_Linux + 310)
#define __NR_kcmp (__NR_Linux + 311)
#define __NR_finit_module (__NR_Linux + 312)
+/* Backporting seccomp, skip a few ...
+ * #define __NR_sched_setattr (__NR_Linux + 313)
+ * #define __NR_sched_getattr (__NR_Linux + 314)
+ * #define __NR_renameat2 (__NR_Linux + 315)
+ */
+#define __NR_seccomp (__NR_Linux + 316)
/*
* Offset of the last N32 flavoured syscall
*/
-#define __NR_Linux_syscalls 312
+#define __NR_Linux_syscalls 316
#endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
#define __NR_N32_Linux 6000
-#define __NR_N32_Linux_syscalls 312
+#define __NR_N32_Linux_syscalls 316
#endif /* _UAPI_ASM_UNISTD_H */
diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c
index 46c2ad0703a..63b942f613c 100644
--- a/arch/mips/kernel/branch.c
+++ b/arch/mips/kernel/branch.c
@@ -200,7 +200,7 @@ int __MIPS16e_compute_return_epc(struct pt_regs *regs)
*
* @regs: Pointer to pt_regs
* @insn: branch instruction to decode
- * @returns: -EFAULT on error and forces SIGBUS, and on success
+ * @returns: -EFAULT on error and forces SIGILL, and on success
* returns 0 or BRANCH_LIKELY_TAKEN as appropriate after
* evaluating the branch.
*/
@@ -297,6 +297,7 @@ int __compute_return_epc_for_insn(struct pt_regs *regs,
/*
* These are unconditional and in j_format.
*/
+ case jalx_op:
case jal_op:
regs->regs[31] = regs->cp0_epc + 8;
case j_op:
@@ -436,8 +437,9 @@ int __compute_return_epc_for_insn(struct pt_regs *regs,
return ret;
sigill:
- printk("%s: DSP branch but not DSP ASE - sending SIGBUS.\n", current->comm);
- force_sig(SIGBUS, current);
+ pr_info("%s: DSP branch but not DSP ASE - sending SIGILL.\n",
+ current->comm);
+ force_sig(SIGILL, current);
return -EFAULT;
}
EXPORT_SYMBOL_GPL(__compute_return_epc_for_insn);
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index ed5bafb5d63..a5a93acdc2c 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -593,6 +593,12 @@ einval: li v0, -ENOSYS
sys sys_process_vm_writev 6
sys sys_kcmp 5
sys sys_finit_module 3
+ /* Backporting seccomp, skip a few ... */
+ sys sys_ni_syscall 0 /* sys_sched_setattr */
+ sys sys_ni_syscall 0 /* sys_sched_getattr */ /* 4350 */
+ sys sys_ni_syscall 0 /* sys_renameat2 */
+ sys sys_seccomp 3
+
.endm
/* We pre-compute the number of _instruction_ bytes needed to
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
index be6627ead61..4220ab5d554 100644
--- a/arch/mips/kernel/scall64-64.S
+++ b/arch/mips/kernel/scall64-64.S
@@ -424,4 +424,8 @@ sys_call_table:
PTR sys_kcmp
PTR sys_finit_module
PTR sys_getdents64
+ sys sys_ni_syscall /* sys_sched_setattr */
+ sys sys_ni_syscall /* sys_sched_getattr */ /* 5310 */
+ sys sys_ni_syscall /* sys_renameat2 */
+ sys sys_seccomp
.size sys_call_table,.-sys_call_table
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index b657fbefc46..de0d435acb4 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -417,4 +417,8 @@ EXPORT(sysn32_call_table)
PTR compat_sys_process_vm_writev /* 6310 */
PTR sys_kcmp
PTR sys_finit_module
+ sys sys_ni_syscall /* sys_sched_setattr */
+ sys sys_ni_syscall /* sys_sched_getattr */
+ sys sys_ni_syscall /* sys_renameat2 */ /* 6315 */
+ sys sys_seccomp
.size sysn32_call_table,.-sysn32_call_table
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index bf56d7e271d..b32e2dfbb9c 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -541,4 +541,8 @@ sys_call_table:
PTR compat_sys_process_vm_writev
PTR sys_kcmp
PTR sys_finit_module
- .size sys_call_table,.-sys_call_table
+ sys sys_ni_syscall /* sys_sched_setattr */
+ sys sys_ni_syscall /* sys_sched_getattr */ /* 4350 */
+ sys sys_ni_syscall /* sys_renameat2 */
+ sys sys_seccomp
+ .size sys32_call_table,.-sys32_call_table
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index b79d13f95bf..eb0f4dfb385 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -140,7 +140,7 @@ static inline int mips_atomic_set(unsigned long addr, unsigned long new)
"1: ll %[old], (%[addr]) \n"
" move %[tmp], %[new] \n"
"2: sc %[tmp], (%[addr]) \n"
- " bnez %[tmp], 4f \n"
+ " beqz %[tmp], 4f \n"
"3: \n"
" .subsection 2 \n"
"4: b 1b \n"
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index 3d492a823a5..dbddc9ccf27 100644
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -2002,6 +2002,35 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
return 0;
}
+/*
+ * Emulate FPU instructions.
+ *
+ * If we use FPU hardware, then we have been typically called to handle
+ * an unimplemented operation, such as where an operand is a NaN or
+ * denormalized. In that case exit the emulation loop after a single
+ * iteration so as to let hardware execute any subsequent instructions.
+ *
+ * If we have no FPU hardware or it has been disabled, then continue
+ * emulating floating-point instructions until one of these conditions
+ * has occurred:
+ *
+ * - a non-FPU instruction has been encountered,
+ *
+ * - an attempt to emulate has ended with a signal,
+ *
+ * - the ISA mode has been switched.
+ *
+ * We need to terminate the emulation loop if we got switched to the
+ * MIPS16 mode, whether supported or not, so that we do not attempt
+ * to emulate a MIPS16 instruction as a regular MIPS FPU instruction.
+ * Similarly if we got switched to the microMIPS mode and only the
+ * regular MIPS mode is supported, so that we do not attempt to emulate
+ * a microMIPS instruction as a regular MIPS FPU instruction. Or if
+ * we got switched to the regular MIPS mode and only the microMIPS mode
+ * is supported, so that we do not attempt to emulate a regular MIPS
+ * instruction that should cause an Address Error exception instead.
+ * For simplicity we always terminate upon an ISA mode switch.
+ */
int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
int has_fpu, void *__user *fault_addr)
{
@@ -2093,6 +2122,15 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
break;
if (sig)
break;
+ /*
+ * We have to check for the ISA bit explicitly here,
+ * because `get_isa16_mode' may return 0 if support
+ * for code compression has been globally disabled,
+ * or otherwise we may produce the wrong signal or
+ * even proceed successfully where we must not.
+ */
+ if ((xcp->cp0_epc ^ prevepc) & 0x1)
+ break;
cond_resched();
} while (xcp->cp0_epc > prevepc);
diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h
index e3b1d41c89b..84bcdfa410f 100644
--- a/arch/powerpc/include/asm/atomic.h
+++ b/arch/powerpc/include/asm/atomic.h
@@ -501,7 +501,7 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
* Atomically increments @v by 1, so long as @v is non-zero.
* Returns non-zero if @v was non-zero, and zero otherwise.
*/
-static __inline__ long atomic64_inc_not_zero(atomic64_t *v)
+static __inline__ int atomic64_inc_not_zero(atomic64_t *v)
{
long t1, t2;
@@ -520,7 +520,7 @@ static __inline__ long atomic64_inc_not_zero(atomic64_t *v)
: "r" (&v->counter)
: "cc", "xer", "memory");
- return t1;
+ return t1 != 0;
}
#endif /* __powerpc64__ */
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 469d7715d6a..954168be787 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -1136,7 +1136,7 @@
" .llong 0\n" \
" .llong 0\n" \
".previous" \
- : "=r" (rval) : "i" (CPU_FTR_CELL_TB_BUG)); rval;})
+ : "=r" (rval) : "i" (CPU_FTR_CELL_TB_BUG) : "cr0"); rval;})
#else
#define mftb() ({unsigned long rval; \
asm volatile("mftb %0" : "=r" (rval)); rval;})
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 11f5b03a0b0..762c10d46d6 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -529,6 +529,15 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc);
#endif
+ /*
+ * jprobes use jprobe_return() which skips the normal return
+ * path of the function, and this messes up the accounting of the
+ * function graph tracer.
+ *
+ * Pause function graph tracing while performing the jprobe function.
+ */
+ pause_graph_tracing();
+
return 1;
}
@@ -551,6 +560,8 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
* saved regs...
*/
memcpy(regs, &kcb->jprobe_saved_regs, sizeof(struct pt_regs));
+ /* It's OK to start function graph tracing again */
+ unpause_graph_tracing();
preempt_enable_no_resched();
return 1;
}
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index 08490ecc465..23da15ff779 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -863,6 +863,19 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
goto instr_done;
#endif
case 19: /* mfcr */
+ if ((instr >> 20) & 1) {
+ imm = 0xf0000000UL;
+ for (sh = 0; sh < 8; ++sh) {
+ if (instr & (0x80000 >> sh)) {
+ regs->gpr[rd] = regs->ccr & imm;
+ break;
+ }
+ imm >>= 4;
+ }
+
+ goto instr_done;
+ }
+
regs->gpr[rd] = regs->ccr;
regs->gpr[rd] &= 0xffffffffUL;
goto instr_done;
diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index d8e8eefbe24..86ec87dc1f5 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -296,13 +296,13 @@ static inline unsigned type in##bwl##_p(int port) \
static inline void outs##bwl(int port, const void *addr, unsigned long count) \
{ \
asm volatile("rep; outs" #bwl \
- : "+S"(addr), "+c"(count) : "d"(port)); \
+ : "+S"(addr), "+c"(count) : "d"(port) : "memory"); \
} \
\
static inline void ins##bwl(int port, void *addr, unsigned long count) \
{ \
asm volatile("rep; ins" #bwl \
- : "+D"(addr), "+c"(count) : "d"(port)); \
+ : "+D"(addr), "+c"(count) : "d"(port) : "memory"); \
}
BUILDIO(b, b, char)
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 3cd8bfc3c4b..bc37ddeaa62 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -1581,8 +1581,10 @@ void __init enable_IR_x2apic(void)
int ret, x2apic_enabled = 0;
int hardware_init_ret;
+#ifdef CONFIG_X86_IO_APIC
if (skip_ioapic_setup)
return;
+#endif
/* Make sure irq_remap_ops are initialized */
setup_irq_remapping_ops();
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index c4ff2a91613..c95ece93f35 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -159,8 +159,8 @@ void kvm_async_pf_task_wait(u32 token)
*/
rcu_irq_exit();
native_safe_halt();
- rcu_irq_enter();
local_irq_disable();
+ rcu_irq_enter();
}
}
if (!n.halted)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index d9016e4a80f..be138952728 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -8014,7 +8014,7 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu,
* (KVM doesn't change it)- no reason to call set_cr4_guest_host_mask();
*/
vcpu->arch.cr4_guest_owned_bits = ~vmcs_readl(CR4_GUEST_HOST_MASK);
- kvm_set_cr4(vcpu, vmcs12->host_cr4);
+ vmx_set_cr4(vcpu, vmcs12->host_cr4);
/* shadow page tables on either EPT or shadow page tables */
kvm_set_cr3(vcpu, vmcs12->host_cr3);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index b70b67bde90..3d316cafff9 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4596,6 +4596,8 @@ static bool emulator_get_segment(struct x86_emulate_ctxt *ctxt, u16 *selector,
if (var.unusable) {
memset(desc, 0, sizeof(*desc));
+ if (base3)
+ *base3 = 0;
return false;
}
diff --git a/arch/x86/mm/numa_32.c b/arch/x86/mm/numa_32.c
index 73a6d7395bd..58e7e9d4bbc 100644
--- a/arch/x86/mm/numa_32.c
+++ b/arch/x86/mm/numa_32.c
@@ -100,5 +100,6 @@ void __init initmem_init(void)
printk(KERN_DEBUG "High memory starts at vaddr %08lx\n",
(ulong) pfn_to_kaddr(highstart_pfn));
+ __vmalloc_start_set = true;
setup_bootmem_allocator();
}
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
index 3c9f13059b1..014984d199e 100644
--- a/block/bfq-iosched.c
+++ b/block/bfq-iosched.c
@@ -80,7 +80,7 @@ static const int bfq_back_max = 16 * 1024;
static const int bfq_back_penalty = 2;
/* Idling period duration, in jiffies. */
-static int bfq_slice_idle = 0;
+static int bfq_slice_idle = HZ / 125;
/* Default maximum budget values, in sectors and number of requests. */
static const int bfq_default_max_budget = 16 * 1024;
@@ -4170,6 +4170,12 @@ static struct elevator_type iosched_bfq = {
static int __init bfq_init(void)
{
+ /*
+ * Can be 0 on HZ < 1000 setups.
+ */
+ if (bfq_slice_idle == 0)
+ bfq_slice_idle = 1;
+
if (bfq_timeout_async == 0)
bfq_timeout_async = 1;
diff --git a/block/bfq-sched.c b/block/bfq-sched.c
index c3828a45b67..d0890c6d4c1 100644
--- a/block/bfq-sched.c
+++ b/block/bfq-sched.c
@@ -1046,9 +1046,6 @@ static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd,
entity = __bfq_lookup_next_entity(st + i, false);
if (entity != NULL) {
if (extract) {
- if (sd->next_in_service != entity) {
- entity = __bfq_lookup_next_entity(st + i, true);
- }
bfq_check_next_in_service(sd, entity);
bfq_active_extract(st + i, entity);
sd->in_service_entity = entity;
diff --git a/block/blk-ioc.c b/block/blk-ioc.c
index 4464c823cff..9c4bb8266bc 100644
--- a/block/blk-ioc.c
+++ b/block/blk-ioc.c
@@ -144,8 +144,7 @@ void put_io_context(struct io_context *ioc)
if (atomic_long_dec_and_test(&ioc->refcount)) {
spin_lock_irqsave(&ioc->lock, flags);
if (!hlist_empty(&ioc->icq_list))
- queue_work(system_power_efficient_wq,
- &ioc->release_work);
+ schedule_work(&ioc->release_work);
else
free_ioc = true;
spin_unlock_irqrestore(&ioc->lock, flags);
diff --git a/block/genhd.c b/block/genhd.c
index cfca0645088..a240c76be9b 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -1515,11 +1515,9 @@ static void __disk_unblock_events(struct gendisk *disk, bool check_now)
intv = disk_events_poll_jiffies(disk);
set_timer_slack(&ev->dwork.timer, intv / 4);
if (check_now)
- queue_delayed_work(system_freezable_power_efficient_wq,
- &ev->dwork, 0);
+ queue_delayed_work(system_freezable_wq, &ev->dwork, 0);
else if (intv)
- queue_delayed_work(system_freezable_power_efficient_wq,
- &ev->dwork, intv);
+ queue_delayed_work(system_freezable_wq, &ev->dwork, intv);
out_unlock:
spin_unlock_irqrestore(&ev->lock, flags);
}
@@ -1562,8 +1560,7 @@ void disk_flush_events(struct gendisk *disk, unsigned int mask)
spin_lock_irq(&ev->lock);
ev->clearing |= mask;
if (!ev->block)
- mod_delayed_work(system_freezable_power_efficient_wq,
- &ev->dwork, 0);
+ mod_delayed_work(system_freezable_wq, &ev->dwork, 0);
spin_unlock_irq(&ev->lock);
}
@@ -1656,8 +1653,7 @@ static void disk_check_events(struct disk_events *ev,
intv = disk_events_poll_jiffies(disk);
if (!ev->block && intv)
- queue_delayed_work(system_freezable_power_efficient_wq,
- &ev->dwork, intv);
+ queue_delayed_work(system_freezable_wq, &ev->dwork, intv);
spin_unlock_irq(&ev->lock);
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
index ea05c531db2..8e2747401d3 100644
--- a/crypto/algif_skcipher.c
+++ b/crypto/algif_skcipher.c
@@ -92,8 +92,10 @@ static int skcipher_alloc_sgl(struct sock *sk)
sg_init_table(sgl->sg, MAX_SGL_ENTS + 1);
sgl->cur = 0;
- if (sg)
+ if (sg) {
scatterwalk_sg_chain(sg, MAX_SGL_ENTS + 1, sgl->sg);
+ sg_unmark_end(sg + (MAX_SGL_ENTS - 1));
+ }
list_add_tail(&sgl->list, &ctx->tsgl);
}
diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c
index 8a66221d95b..496557a15f7 100644
--- a/crypto/blkcipher.c
+++ b/crypto/blkcipher.c
@@ -233,8 +233,6 @@ static int blkcipher_walk_next(struct blkcipher_desc *desc,
return blkcipher_walk_done(desc, walk, -EINVAL);
}
- bsize = min(walk->walk_blocksize, n);
-
walk->flags &= ~(BLKCIPHER_WALK_SLOW | BLKCIPHER_WALK_COPY |
BLKCIPHER_WALK_DIFF);
if (!scatterwalk_aligned(&walk->in, walk->alignmask) ||
@@ -247,6 +245,7 @@ static int blkcipher_walk_next(struct blkcipher_desc *desc,
}
}
+ bsize = min(walk->walk_blocksize, n);
n = scatterwalk_clamp(&walk->in, n);
n = scatterwalk_clamp(&walk->out, n);
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 070b843c37e..8cff7cae733 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -988,6 +988,7 @@ static int ghes_remove(struct platform_device *ghes_dev)
if (list_empty(&ghes_sci))
unregister_acpi_hed_notifier(&ghes_notifier_sci);
mutex_unlock(&ghes_list_mutex);
+ synchronize_rcu();
break;
case ACPI_HEST_NOTIFY_NMI:
mutex_lock(&ghes_list_mutex);
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c
index fcae5fa2e1b..95b6371e1fe 100644
--- a/drivers/acpi/sysfs.c
+++ b/drivers/acpi/sysfs.c
@@ -492,23 +492,22 @@ static void acpi_global_event_handler(u32 event_type, acpi_handle device,
static int get_status(u32 index, acpi_event_status *status,
acpi_handle *handle)
{
- int result = 0;
+ int result;
if (index >= num_gpes + ACPI_NUM_FIXED_EVENTS)
- goto end;
+ return -EINVAL;
if (index < num_gpes) {
result = acpi_get_gpe_device(index, handle);
if (result) {
ACPI_EXCEPTION((AE_INFO, AE_NOT_FOUND,
"Invalid GPE 0x%x", index));
- goto end;
+ return result;
}
result = acpi_get_gpe_status(*handle, index, status);
} else if (index < (num_gpes + ACPI_NUM_FIXED_EVENTS))
result = acpi_get_event_status(index - num_gpes, status);
-end:
return result;
}
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 2516c8bd12b..2e18e6d9508 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2132,7 +2132,7 @@ static void binder_transaction(struct binder_proc *proc,
if (!IS_ALIGNED(extra_buffers_size, sizeof(u64))) {
binder_user_error("%d:%d got transaction with unaligned buffers size, %lld\n",
proc->pid, thread->pid,
- extra_buffers_size);
+ (u64)extra_buffers_size);
return_error = BR_FAILED_REPLY;
goto err_bad_offset;
}
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index f3f0801a0e8..aa4e36b3a59 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -2794,10 +2794,12 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
static struct ata_device *ata_find_dev(struct ata_port *ap, int devno)
{
if (!sata_pmp_attached(ap)) {
- if (likely(devno < ata_link_max_devices(&ap->link)))
+ if (likely(devno >= 0 &&
+ devno < ata_link_max_devices(&ap->link)))
return &ap->link.device[devno];
} else {
- if (likely(devno < ap->nr_pmp_links))
+ if (likely(devno >= 0 &&
+ devno < ap->nr_pmp_links))
return &ap->pmp_link[devno].device[0];
}
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 36b92969858..a1b4e620f96 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -1161,7 +1161,8 @@ done:
kobject_del(&dev->kobj);
Error:
cleanup_glue_dir(dev, glue_dir);
- put_device(parent);
+ if (parent)
+ put_device(parent);
name_error:
kfree(dev->p);
dev->p = NULL;
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index dd19658d5a8..563b63f3876 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -1066,8 +1066,7 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent,
dev_set_uevent_suppress(f_dev, false);
dev_dbg(f_dev, "firmware: requesting %s\n", buf->fw_id);
if (timeout != MAX_SCHEDULE_TIMEOUT)
- queue_delayed_work(system_power_efficient_wq,
- &fw_priv->timeout_work, timeout);
+ schedule_delayed_work(&fw_priv->timeout_work, timeout);
kobject_uevent(&fw_priv->dev.kobj, KOBJ_ADD);
}
@@ -1772,8 +1771,8 @@ static void device_uncache_fw_images_work(struct work_struct *work)
*/
static void device_uncache_fw_images_delay(unsigned long delay)
{
- queue_delayed_work(system_power_efficient_wq, &fw_cache.work,
- msecs_to_jiffies(delay));
+ schedule_delayed_work(&fw_cache.work,
+ msecs_to_jiffies(delay));
}
static int fw_pm_notify(struct notifier_block *notify_block,
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 95009a2ffcc..12508dbd0b0 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -1692,7 +1692,7 @@ int pm_genpd_add_subdomain_names(const char *master_name,
int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
struct generic_pm_domain *subdomain)
{
- struct gpd_link *link;
+ struct gpd_link *l, *link;
int ret = -EINVAL;
if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain))
@@ -1701,7 +1701,7 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
start:
genpd_acquire_lock(genpd);
- list_for_each_entry(link, &genpd->master_links, master_node) {
+ list_for_each_entry_safe(link, l, &genpd->master_links, master_node) {
if (link->slave != subdomain)
continue;
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 72d1bdd3630..6847c618ca8 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -28,6 +28,7 @@
#include <linux/sched.h>
#include <linux/async.h>
#include <linux/suspend.h>
+#include <linux/cpuidle.h>
#include <linux/timer.h>
#include <linux/wakeup_reason.h>
diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c
index 8066a7d7b22..4f034ee9a90 100644
--- a/drivers/base/power/wakeup.c
+++ b/drivers/base/power/wakeup.c
@@ -15,18 +15,10 @@
#include <linux/seq_file.h>
#include <linux/debugfs.h>
#include <linux/types.h>
-#include <linux/moduleparam.h>
#include <trace/events/power.h>
#include "power.h"
-static bool enable_qcom_rx_wakelock_ws = true;
-module_param(enable_qcom_rx_wakelock_ws, bool, 0644);
-static bool enable_wlan_extscan_wl_ws = true;
-module_param(enable_wlan_extscan_wl_ws, bool, 0644);
-static bool enable_ipa_ws = true;
-module_param(enable_ipa_ws, bool, 0644);
-
/*
* If set, the suspend/hibernate code will abort transitions to a sleep state
* if wakeup events are registered during or immediately before the transition.
@@ -382,73 +374,6 @@ int device_set_wakeup_enable(struct device *dev, bool enable)
}
EXPORT_SYMBOL_GPL(device_set_wakeup_enable);
-#ifdef CONFIG_PM_AUTOSLEEP
-static void update_prevent_sleep_time(struct wakeup_source *ws, ktime_t now)
-{
- ktime_t delta = ktime_sub(now, ws->start_prevent_time);
- ws->prevent_sleep_time = ktime_add(ws->prevent_sleep_time, delta);
-}
-#else
-static inline void update_prevent_sleep_time(struct wakeup_source *ws,
- ktime_t now) {}
-#endif
-
-/**
- * wakup_source_deactivate - Mark given wakeup source as inactive.
- * @ws: Wakeup source to handle.
- *
- * Update the @ws' statistics and notify the PM core that the wakeup source has
- * become inactive by decrementing the counter of wakeup events being processed
- * and incrementing the counter of registered wakeup events.
- */
-static void wakeup_source_deactivate(struct wakeup_source *ws)
-{
- unsigned int cnt, inpr, cec;
- ktime_t duration;
- ktime_t now;
-
- ws->relax_count++;
- /*
- * __pm_relax() may be called directly or from a timer function.
- * If it is called directly right after the timer function has been
- * started, but before the timer function calls __pm_relax(), it is
- * possible that __pm_stay_awake() will be called in the meantime and
- * will set ws->active. Then, ws->active may be cleared immediately
- * by the __pm_relax() called from the timer function, but in such a
- * case ws->relax_count will be different from ws->active_count.
- */
- if (ws->relax_count != ws->active_count) {
- ws->relax_count--;
- return;
- }
-
- ws->active = false;
-
- now = ktime_get();
- duration = ktime_sub(now, ws->last_time);
- ws->total_time = ktime_add(ws->total_time, duration);
- if (ktime_to_ns(duration) > ktime_to_ns(ws->max_time))
- ws->max_time = duration;
-
- ws->last_time = now;
- del_timer(&ws->timer);
- ws->timer_expires = 0;
-
- if (ws->autosleep_enabled)
- update_prevent_sleep_time(ws, now);
-
- /*
- * Increment the counter of registered wakeup events and decrement the
- * couter of wakeup events in progress simultaneously.
- */
- cec = atomic_add_return(MAX_IN_PROGRESS, &combined_event_count);
- trace_wakeup_source_deactivate(ws->name, cec);
-
- split_counters(&cnt, &inpr);
- if (!inpr && waitqueue_active(&wakeup_count_wait_queue))
- wake_up(&wakeup_count_wait_queue);
-}
-
/**
* wakeup_source_not_registered - validate the given wakeup source.
* @ws: Wakeup source to be validated.
@@ -503,17 +428,6 @@ static void wakeup_source_activate(struct wakeup_source *ws)
{
unsigned int cec;
- if ((!enable_ipa_ws && !strncmp(ws->name, "IPA_WS", 6)) ||
- (!enable_wlan_extscan_wl_ws &&
- !strncmp(ws->name, "wlan_extscan_wl", 15)) ||
- (!enable_qcom_rx_wakelock_ws &&
- !strncmp(ws->name, "qcom_rx_wakelock", 16))) {
- if (ws->active)
- wakeup_source_deactivate(ws);
-
- return;
- }
-
if (WARN(wakeup_source_not_registered(ws),
"unregistered wakeup source\n"))
return;
@@ -598,6 +512,73 @@ void pm_stay_awake(struct device *dev)
}
EXPORT_SYMBOL_GPL(pm_stay_awake);
+#ifdef CONFIG_PM_AUTOSLEEP
+static void update_prevent_sleep_time(struct wakeup_source *ws, ktime_t now)
+{
+ ktime_t delta = ktime_sub(now, ws->start_prevent_time);
+ ws->prevent_sleep_time = ktime_add(ws->prevent_sleep_time, delta);
+}
+#else
+static inline void update_prevent_sleep_time(struct wakeup_source *ws,
+ ktime_t now) {}
+#endif
+
+/**
+ * wakup_source_deactivate - Mark given wakeup source as inactive.
+ * @ws: Wakeup source to handle.
+ *
+ * Update the @ws' statistics and notify the PM core that the wakeup source has
+ * become inactive by decrementing the counter of wakeup events being processed
+ * and incrementing the counter of registered wakeup events.
+ */
+static void wakeup_source_deactivate(struct wakeup_source *ws)
+{
+ unsigned int cnt, inpr, cec;
+ ktime_t duration;
+ ktime_t now;
+
+ ws->relax_count++;
+ /*
+ * __pm_relax() may be called directly or from a timer function.
+ * If it is called directly right after the timer function has been
+ * started, but before the timer function calls __pm_relax(), it is
+ * possible that __pm_stay_awake() will be called in the meantime and
+ * will set ws->active. Then, ws->active may be cleared immediately
+ * by the __pm_relax() called from the timer function, but in such a
+ * case ws->relax_count will be different from ws->active_count.
+ */
+ if (ws->relax_count != ws->active_count) {
+ ws->relax_count--;
+ return;
+ }
+
+ ws->active = false;
+
+ now = ktime_get();
+ duration = ktime_sub(now, ws->last_time);
+ ws->total_time = ktime_add(ws->total_time, duration);
+ if (ktime_to_ns(duration) > ktime_to_ns(ws->max_time))
+ ws->max_time = duration;
+
+ ws->last_time = now;
+ del_timer(&ws->timer);
+ ws->timer_expires = 0;
+
+ if (ws->autosleep_enabled)
+ update_prevent_sleep_time(ws, now);
+
+ /*
+ * Increment the counter of registered wakeup events and decrement the
+ * couter of wakeup events in progress simultaneously.
+ */
+ cec = atomic_add_return(MAX_IN_PROGRESS, &combined_event_count);
+ trace_wakeup_source_deactivate(ws->name, cec);
+
+ split_counters(&cnt, &inpr);
+ if (!inpr && waitqueue_active(&wakeup_count_wait_queue))
+ wake_up(&wakeup_count_wait_queue);
+}
+
/**
* __pm_relax - Notify the PM core that processing of a wakeup event has ended.
* @ws: Wakeup source object associated with the source of the event.
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 5643de97bee..a2fd0bc62fa 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -601,6 +601,10 @@ config DEVPORT
Say Y here if you want to support the /dev/port device. The /dev/port
device is similar to /dev/mem, but for I/O ports.
+config DCC_TTY
+ tristate "DCC tty driver"
+ depends on ARM
+
source "drivers/s390/char/Kconfig"
config MSM_SMD_PKT
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index befc95e19ab..6d8c70b77b1 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -55,6 +55,7 @@ obj-$(CONFIG_PCMCIA) += pcmcia/
obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o
obj-$(CONFIG_TCG_TPM) += tpm/
+obj-$(CONFIG_DCC_TTY) += dcc_tty.o
obj-$(CONFIG_PS3_FLASH) += ps3flash.o
obj-$(CONFIG_JS_RTC) += js-rtc.o
diff --git a/drivers/char/dcc_tty.c b/drivers/char/dcc_tty.c
new file mode 100644
index 00000000000..a787accdcb1
--- /dev/null
+++ b/drivers/char/dcc_tty.c
@@ -0,0 +1,326 @@
+/* drivers/char/dcc_tty.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/console.h>
+#include <linux/hrtimer.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+
+MODULE_DESCRIPTION("DCC TTY Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("1.0");
+
+static spinlock_t g_dcc_tty_lock = SPIN_LOCK_UNLOCKED;
+static struct hrtimer g_dcc_timer;
+static char g_dcc_buffer[16];
+static int g_dcc_buffer_head;
+static int g_dcc_buffer_count;
+static unsigned g_dcc_write_delay_usecs = 1;
+static struct tty_driver *g_dcc_tty_driver;
+static struct tty_struct *g_dcc_tty;
+static int g_dcc_tty_open_count;
+
+static void dcc_poll_locked(void)
+{
+ char ch;
+ int rch;
+ int written;
+
+ while (g_dcc_buffer_count) {
+ ch = g_dcc_buffer[g_dcc_buffer_head];
+ asm(
+ "mrc 14, 0, r15, c0, c1, 0\n"
+ "mcrcc 14, 0, %1, c0, c5, 0\n"
+ "movcc %0, #1\n"
+ "movcs %0, #0\n"
+ : "=r" (written)
+ : "r" (ch)
+ );
+ if (written) {
+ if (ch == '\n')
+ g_dcc_buffer[g_dcc_buffer_head] = '\r';
+ else {
+ g_dcc_buffer_head = (g_dcc_buffer_head + 1) % ARRAY_SIZE(g_dcc_buffer);
+ g_dcc_buffer_count--;
+ if (g_dcc_tty)
+ tty_wakeup(g_dcc_tty);
+ }
+ g_dcc_write_delay_usecs = 1;
+ } else {
+ if (g_dcc_write_delay_usecs > 0x100)
+ break;
+ g_dcc_write_delay_usecs <<= 1;
+ udelay(g_dcc_write_delay_usecs);
+ }
+ }
+
+ if (g_dcc_tty && !test_bit(TTY_THROTTLED, &g_dcc_tty->flags)) {
+ asm(
+ "mrc 14, 0, %0, c0, c1, 0\n"
+ "tst %0, #(1 << 30)\n"
+ "moveq %0, #-1\n"
+ "mrcne 14, 0, %0, c0, c5, 0\n"
+ : "=r" (rch)
+ );
+ if (rch >= 0) {
+ ch = rch;
+ tty_insert_flip_string(g_dcc_tty, &ch, 1);
+ tty_flip_buffer_push(g_dcc_tty);
+ }
+ }
+
+
+ if (g_dcc_buffer_count)
+ hrtimer_start(&g_dcc_timer, ktime_set(0, g_dcc_write_delay_usecs * NSEC_PER_USEC), HRTIMER_MODE_REL);
+ else
+ hrtimer_start(&g_dcc_timer, ktime_set(0, 20 * NSEC_PER_MSEC), HRTIMER_MODE_REL);
+}
+
+static int dcc_tty_open(struct tty_struct * tty, struct file * filp)
+{
+ int ret;
+ unsigned long irq_flags;
+
+ spin_lock_irqsave(&g_dcc_tty_lock, irq_flags);
+ if (g_dcc_tty == NULL || g_dcc_tty == tty) {
+ g_dcc_tty = tty;
+ g_dcc_tty_open_count++;
+ ret = 0;
+ } else
+ ret = -EBUSY;
+ spin_unlock_irqrestore(&g_dcc_tty_lock, irq_flags);
+
+ printk("dcc_tty_open, tty %p, f_flags %x, returned %d\n", tty, filp->f_flags, ret);
+
+ return ret;
+}
+
+static void dcc_tty_close(struct tty_struct * tty, struct file * filp)
+{
+ printk("dcc_tty_close, tty %p, f_flags %x\n", tty, filp->f_flags);
+ if (g_dcc_tty == tty) {
+ if (--g_dcc_tty_open_count == 0)
+ g_dcc_tty = NULL;
+ }
+}
+
+static int dcc_write(const unsigned char *buf_start, int count)
+{
+ const unsigned char *buf = buf_start;
+ unsigned long irq_flags;
+ int copy_len;
+ int space_left;
+ int tail;
+
+ if (count < 1)
+ return 0;
+
+ spin_lock_irqsave(&g_dcc_tty_lock, irq_flags);
+ do {
+ tail = (g_dcc_buffer_head + g_dcc_buffer_count) % ARRAY_SIZE(g_dcc_buffer);
+ copy_len = ARRAY_SIZE(g_dcc_buffer) - tail;
+ space_left = ARRAY_SIZE(g_dcc_buffer) - g_dcc_buffer_count;
+ if (copy_len > space_left)
+ copy_len = space_left;
+ if (copy_len > count)
+ copy_len = count;
+ memcpy(&g_dcc_buffer[tail], buf, copy_len);
+ g_dcc_buffer_count += copy_len;
+ buf += copy_len;
+ count -= copy_len;
+ if (copy_len < count && copy_len < space_left) {
+ space_left -= copy_len;
+ copy_len = count;
+ if (copy_len > space_left) {
+ copy_len = space_left;
+ }
+ memcpy(g_dcc_buffer, buf, copy_len);
+ buf += copy_len;
+ count -= copy_len;
+ g_dcc_buffer_count += copy_len;
+ }
+ dcc_poll_locked();
+ space_left = ARRAY_SIZE(g_dcc_buffer) - g_dcc_buffer_count;
+ } while(count && space_left);
+ spin_unlock_irqrestore(&g_dcc_tty_lock, irq_flags);
+ return buf - buf_start;
+}
+
+static int dcc_tty_write(struct tty_struct * tty, const unsigned char *buf, int count)
+{
+ int ret;
+ /* printk("dcc_tty_write %p, %d\n", buf, count); */
+ ret = dcc_write(buf, count);
+ if (ret != count)
+ printk("dcc_tty_write %p, %d, returned %d\n", buf, count, ret);
+ return ret;
+}
+
+static int dcc_tty_write_room(struct tty_struct *tty)
+{
+ int space_left;
+ unsigned long irq_flags;
+
+ spin_lock_irqsave(&g_dcc_tty_lock, irq_flags);
+ space_left = ARRAY_SIZE(g_dcc_buffer) - g_dcc_buffer_count;
+ spin_unlock_irqrestore(&g_dcc_tty_lock, irq_flags);
+ return space_left;
+}
+
+static int dcc_tty_chars_in_buffer(struct tty_struct *tty)
+{
+ int ret;
+ asm(
+ "mrc 14, 0, %0, c0, c1, 0\n"
+ "mov %0, %0, LSR #30\n"
+ "and %0, %0, #1\n"
+ : "=r" (ret)
+ );
+ return ret;
+}
+
+static void dcc_tty_unthrottle(struct tty_struct * tty)
+{
+ unsigned long irq_flags;
+
+ spin_lock_irqsave(&g_dcc_tty_lock, irq_flags);
+ dcc_poll_locked();
+ spin_unlock_irqrestore(&g_dcc_tty_lock, irq_flags);
+}
+
+static enum hrtimer_restart dcc_tty_timer_func(struct hrtimer *timer)
+{
+ unsigned long irq_flags;
+
+ spin_lock_irqsave(&g_dcc_tty_lock, irq_flags);
+ dcc_poll_locked();
+ spin_unlock_irqrestore(&g_dcc_tty_lock, irq_flags);
+ return HRTIMER_NORESTART;
+}
+
+void dcc_console_write(struct console *co, const char *b, unsigned count)
+{
+#if 1
+ dcc_write(b, count);
+#else
+ /* blocking printk */
+ while (count > 0) {
+ int written;
+ written = dcc_write(b, count);
+ if (written) {
+ b += written;
+ count -= written;
+ }
+ }
+#endif
+}
+
+static struct tty_driver *dcc_console_device(struct console *c, int *index)
+{
+ *index = 0;
+ return g_dcc_tty_driver;
+}
+
+static int __init dcc_console_setup(struct console *co, char *options)
+{
+ if (co->index != 0)
+ return -ENODEV;
+ return 0;
+}
+
+
+static struct console dcc_console =
+{
+ .name = "ttyDCC",
+ .write = dcc_console_write,
+ .device = dcc_console_device,
+ .setup = dcc_console_setup,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+};
+
+static struct tty_operations dcc_tty_ops = {
+ .open = dcc_tty_open,
+ .close = dcc_tty_close,
+ .write = dcc_tty_write,
+ .write_room = dcc_tty_write_room,
+ .chars_in_buffer = dcc_tty_chars_in_buffer,
+ .unthrottle = dcc_tty_unthrottle,
+};
+
+static int __init dcc_tty_init(void)
+{
+ int ret;
+
+ hrtimer_init(&g_dcc_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ g_dcc_timer.function = dcc_tty_timer_func;
+
+ g_dcc_tty_driver = alloc_tty_driver(1);
+ if (!g_dcc_tty_driver) {
+ printk(KERN_ERR "dcc_tty_probe: alloc_tty_driver failed\n");
+ ret = -ENOMEM;
+ goto err_alloc_tty_driver_failed;
+ }
+ g_dcc_tty_driver->owner = THIS_MODULE;
+ g_dcc_tty_driver->driver_name = "dcc";
+ g_dcc_tty_driver->name = "ttyDCC";
+ g_dcc_tty_driver->major = 0; // auto assign
+ g_dcc_tty_driver->minor_start = 0;
+ g_dcc_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
+ g_dcc_tty_driver->subtype = SERIAL_TYPE_NORMAL;
+ g_dcc_tty_driver->init_termios = tty_std_termios;
+ g_dcc_tty_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
+ tty_set_operations(g_dcc_tty_driver, &dcc_tty_ops);
+ ret = tty_register_driver(g_dcc_tty_driver);
+ if (ret) {
+ printk(KERN_ERR "dcc_tty_probe: tty_register_driver failed, %d\n", ret);
+ goto err_tty_register_driver_failed;
+ }
+ tty_register_device(g_dcc_tty_driver, 0, NULL);
+
+ register_console(&dcc_console);
+ hrtimer_start(&g_dcc_timer, ktime_set(0, 0), HRTIMER_MODE_REL);
+
+ return 0;
+
+err_tty_register_driver_failed:
+ put_tty_driver(g_dcc_tty_driver);
+ g_dcc_tty_driver = NULL;
+err_alloc_tty_driver_failed:
+ return ret;
+}
+
+static void __exit dcc_tty_exit(void)
+{
+ int ret;
+
+ tty_unregister_device(g_dcc_tty_driver, 0);
+ ret = tty_unregister_driver(g_dcc_tty_driver);
+ if (ret < 0) {
+ printk(KERN_ERR "dcc_tty_remove: tty_unregister_driver failed, %d\n", ret);
+ } else {
+ put_tty_driver(g_dcc_tty_driver);
+ }
+ g_dcc_tty_driver = NULL;
+}
+
+module_init(dcc_tty_init);
+module_exit(dcc_tty_exit);
+
+
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 9d908497f89..ab127334032 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -1846,7 +1846,9 @@ long diagchar_ioctl(struct file *filp,
mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_DCI_EVENT_STATUS:
+ mutex_lock(&driver->dci_mutex);
result = diag_ioctl_dci_event_status(ioarg);
+ mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_DCI_CLEAR_LOGS:
mutex_lock(&driver->dci_mutex);
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 24f46c34640..7932c6bc314 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -501,9 +501,6 @@ static ssize_t store_scaling_governor(struct cpufreq_policy *policy,
int ret;
char str_governor[16];
struct cpufreq_policy new_policy;
- char *envp[3];
- char buf1[64];
- char buf2[64];
ret = cpufreq_get_policy(&new_policy, policy->cpu);
if (ret)
@@ -527,13 +524,6 @@ static ssize_t store_scaling_governor(struct cpufreq_policy *policy,
sysfs_notify(&policy->kobj, NULL, "scaling_governor");
- snprintf(buf1, sizeof(buf1), "GOV=%s", policy->governor->name);
- snprintf(buf2, sizeof(buf2), "CPU=%u", policy->cpu);
- envp[0] = buf1;
- envp[1] = buf2;
- envp[2] = NULL;
- kobject_uevent_env(cpufreq_global_kobject, KOBJ_ADD, envp);
-
if (ret)
return ret;
else
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
index 25a70d06c5b..55836a538a6 100644
--- a/drivers/cpufreq/cpufreq_conservative.c
+++ b/drivers/cpufreq/cpufreq_conservative.c
@@ -204,8 +204,8 @@ static ssize_t store_down_threshold(struct dbs_data *dbs_data, const char *buf,
int ret;
ret = sscanf(buf, "%u", &input);
- /* cannot be lower than 11 otherwise freq will not fall */
- if (ret != 1 || input < 11 || input > 100 ||
+ /* cannot be lower than 1 otherwise freq will not fall */
+ if (ret != 1 || input < 1 || input > 100 ||
input >= cs_tuners->up_threshold)
return -EINVAL;
diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
index 58e14414048..521bf7761ae 100644
--- a/drivers/cpufreq/cpufreq_governor.c
+++ b/drivers/cpufreq/cpufreq_governor.c
@@ -131,15 +131,25 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu)
* timer would not have fired during CPU-idle periods. Hence
* an unusually large 'wall_time' (as compared to the sampling
* rate) indicates this scenario.
+ *
+ * prev_load can be zero in two cases and we must recalculate it
+ * for both cases:
+ * - during long idle intervals
+ * - explicitly set to zero
*/
- if (unlikely(wall_time > (2 * sampling_rate)) &&
- j_cdbs->copy_prev_load) {
+ if (unlikely(wall_time > (2 * sampling_rate) &&
+ j_cdbs->prev_load)) {
load = j_cdbs->prev_load;
- j_cdbs->copy_prev_load = false;
+
+ /*
+ * Perform a destructive copy, to ensure that we copy
+ * the previous load only once, upon the first wake-up
+ * from idle.
+ */
+ j_cdbs->prev_load = 0;
} else {
load = 100 * (wall_time - idle_time) / wall_time;
j_cdbs->prev_load = load;
- j_cdbs->copy_prev_load = true;
}
if (load > max_load)
@@ -369,7 +379,6 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
(j_cdbs->prev_cpu_wall - j_cdbs->prev_cpu_idle);
j_cdbs->prev_load = 100 * prev_load /
(unsigned int) j_cdbs->prev_cpu_wall;
- j_cdbs->copy_prev_load = true;
if (ignore_nice)
j_cdbs->prev_cpu_nice =
@@ -414,6 +423,11 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
break;
case CPUFREQ_GOV_LIMITS:
+ mutex_lock(&dbs_data->mutex);
+ if (!cpu_cdbs->cur_policy) {
+ mutex_unlock(&dbs_data->mutex);
+ break;
+ }
mutex_lock(&cpu_cdbs->timer_mutex);
if (policy->max < cpu_cdbs->cur_policy->cur)
__cpufreq_driver_target(cpu_cdbs->cur_policy,
@@ -423,6 +437,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
policy->min, CPUFREQ_RELATION_L);
dbs_check_cpu(dbs_data, cpu);
mutex_unlock(&cpu_cdbs->timer_mutex);
+ mutex_unlock(&dbs_data->mutex);
break;
}
return 0;
diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h
index 2e920847ef7..279318f6753 100644
--- a/drivers/cpufreq/cpufreq_governor.h
+++ b/drivers/cpufreq/cpufreq_governor.h
@@ -134,12 +134,13 @@ struct cpu_dbs_common_info {
u64 prev_cpu_idle;
u64 prev_cpu_wall;
u64 prev_cpu_nice;
- unsigned int prev_load;
/*
- * Flag to ensure that we copy the previous load only once, upon the
- * first wake-up from idle.
+ * Used to keep track of load in the previous interval. However, when
+ * explicitly set to zero, it is used as a flag to ensure that we copy
+ * the previous load to the current interval only once, upon the first
+ * wake-up from idle.
*/
- bool copy_prev_load;
+ unsigned int prev_load;
struct cpufreq_policy *cur_policy;
struct delayed_work work;
/*
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c
index 079e7574289..93e879fa42b 100644
--- a/drivers/cpufreq/cpufreq_interactive.c
+++ b/drivers/cpufreq/cpufreq_interactive.c
@@ -471,6 +471,9 @@ static void __cpufreq_interactive_timer(unsigned long data, bool is_notif)
}
} else {
new_freq = choose_freq(pcpu, loadadjfreq);
+ if (new_freq > tunables->hispeed_freq &&
+ pcpu->target_freq < tunables->hispeed_freq)
+ new_freq = tunables->hispeed_freq;
}
if (cpu_load <= MAX_LOCAL_LOAD &&
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index 90cdb7aa4c0..d0c29bb6a82 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -526,7 +526,7 @@ static void add_all_freq_table(unsigned int freq)
unsigned int size;
size = sizeof(unsigned int) * (all_freq_table->table_size + 1);
all_freq_table->freq_table = krealloc(all_freq_table->freq_table,
- size, GFP_KERNEL);
+ size, GFP_ATOMIC);
if (IS_ERR(all_freq_table->freq_table)) {
pr_warn("Could not reallocate memory for freq_table\n");
all_freq_table->freq_table = NULL;
diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
index 4e32b8fa31d..3458d27f63b 100644
--- a/drivers/cpufreq/freq_table.c
+++ b/drivers/cpufreq/freq_table.c
@@ -115,7 +115,7 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
.driver_data = ~0,
.frequency = 0,
};
- unsigned int diff, i;
+ unsigned int i;
pr_debug("request for target %u kHz (relation: %u) for cpu %u\n",
target_freq, relation, policy->cpu);
@@ -125,7 +125,6 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
suboptimal.frequency = ~0;
break;
case CPUFREQ_RELATION_L:
- case CPUFREQ_RELATION_C:
optimal.frequency = ~0;
break;
}
@@ -163,15 +162,6 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
}
}
break;
- case CPUFREQ_RELATION_C:
- diff = abs(freq - target_freq);
- if (diff < optimal.frequency ||
- (diff == optimal.frequency &&
- freq > table[optimal.driver_data].frequency)) {
- optimal.frequency = diff;
- optimal.driver_data = i;
- }
- break;
}
}
if (optimal.driver_data > i) {
diff --git a/drivers/cpufreq/qcom-cpufreq.c b/drivers/cpufreq/qcom-cpufreq.c
index b71f39cb185..9bb76429935 100644
--- a/drivers/cpufreq/qcom-cpufreq.c
+++ b/drivers/cpufreq/qcom-cpufreq.c
@@ -244,17 +244,13 @@ static int msm_cpufreq_suspend(void)
static int msm_cpufreq_resume(void)
{
- int cpu;
-#ifndef CONFIG_CPU_BOOST
- int ret;
+ int cpu, ret;
struct cpufreq_policy policy;
-#endif
for_each_possible_cpu(cpu) {
per_cpu(cpufreq_suspend, cpu).device_suspended = 0;
}
-#ifndef CONFIG_CPU_BOOST
/*
* Freq request might be rejected during suspend, resulting
* in policy->cur violating min/max constraint.
@@ -276,7 +272,6 @@ static int msm_cpufreq_resume(void)
cpu);
}
put_online_cpus();
-#endif
return NOTIFY_DONE;
}
diff --git a/drivers/cpufreq/s3c2416-cpufreq.c b/drivers/cpufreq/s3c2416-cpufreq.c
index 600c9ad07cd..17fcd1ff49e 100644
--- a/drivers/cpufreq/s3c2416-cpufreq.c
+++ b/drivers/cpufreq/s3c2416-cpufreq.c
@@ -421,7 +421,6 @@ static int __init s3c2416_cpufreq_driver_init(struct cpufreq_policy *policy)
rate = clk_get_rate(s3c_freq->hclk);
if (rate < 133 * 1000 * 1000) {
pr_err("cpufreq: HCLK not at 133MHz\n");
- clk_put(s3c_freq->hclk);
ret = -EINVAL;
goto err_armclk;
}
diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c
index e9d8b235f68..34815a74d90 100644
--- a/drivers/crypto/caam/caamhash.c
+++ b/drivers/crypto/caam/caamhash.c
@@ -476,7 +476,7 @@ static int hash_digest_key(struct caam_hash_ctx *ctx, const u8 *key_in,
ret = caam_jr_enqueue(jrdev, desc, split_key_done, &result);
if (!ret) {
/* in progress */
- wait_for_completion_interruptible(&result.completion);
+ wait_for_completion(&result.completion);
ret = result.err;
#ifdef DEBUG
print_hex_dump(KERN_ERR, "digested key@"xstr(__LINE__)": ",
diff --git a/drivers/crypto/caam/key_gen.c b/drivers/crypto/caam/key_gen.c
index 87138d2adb5..fd6bc0bc56c 100644
--- a/drivers/crypto/caam/key_gen.c
+++ b/drivers/crypto/caam/key_gen.c
@@ -107,7 +107,7 @@ int gen_split_key(struct device *jrdev, u8 *key_out, int split_key_len,
ret = caam_jr_enqueue(jrdev, desc, split_key_done, &result);
if (!ret) {
/* in progress */
- wait_for_completion_interruptible(&result.completion);
+ wait_for_completion(&result.completion);
ret = result.err;
#ifdef DEBUG
print_hex_dump(KERN_ERR, "ctx.key@"xstr(__LINE__)": ",
diff --git a/drivers/crypto/msm/compat_qcedev.c b/drivers/crypto/msm/compat_qcedev.c
index 97ae990b537..08a764e25ef 100644
--- a/drivers/crypto/msm/compat_qcedev.c
+++ b/drivers/crypto/msm/compat_qcedev.c
@@ -1,7 +1,7 @@
/*
* QTI CE 32-bit compatibility syscall for 64-bit systems
*
- * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014, 2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -97,7 +97,6 @@ static int compat_get_qcedev_vbuf_info(
for (i = 0; i < QCEDEV_MAX_BUFFERS; i++) {
err |= get_user(vaddr, &vbuf32->src[i].vaddr);
- vbuf->src[i].vaddr = NULL;
err |= put_user(vaddr, (compat_uptr_t *)&vbuf->src[i].vaddr);
err |= get_user(len, &vbuf32->src[i].len);
err |= put_user(len, &vbuf->src[i].len);
@@ -105,7 +104,6 @@ static int compat_get_qcedev_vbuf_info(
for (i = 0; i < QCEDEV_MAX_BUFFERS; i++) {
err |= get_user(vaddr, &vbuf32->dst[i].vaddr);
- vbuf->dst[i].vaddr = NULL;
err |= put_user(vaddr, (compat_uptr_t *)&vbuf->dst[i].vaddr);
err |= get_user(len, &vbuf32->dst[i].len);
err |= put_user(len, &vbuf->dst[i].len);
@@ -123,7 +121,6 @@ static int compat_put_qcedev_vbuf_info(
for (i = 0; i < QCEDEV_MAX_BUFFERS; i++) {
err |= get_user(vaddr, (compat_uptr_t *)&vbuf->src[i].vaddr);
- vbuf32->src[i].vaddr = 0;
err |= put_user(vaddr, &vbuf32->src[i].vaddr);
err |= get_user(len, &vbuf->src[i].len);
err |= put_user(len, &vbuf32->src[i].len);
@@ -131,7 +128,6 @@ static int compat_put_qcedev_vbuf_info(
for (i = 0; i < QCEDEV_MAX_BUFFERS; i++) {
err |= get_user(vaddr, (compat_uptr_t *)&vbuf->dst[i].vaddr);
- vbuf32->dst[i].vaddr = 0;
err |= put_user(vaddr, &vbuf32->dst[i].vaddr);
err |= get_user(len, &vbuf->dst[i].len);
err |= put_user(len, &vbuf32->dst[i].len);
@@ -276,7 +272,6 @@ static int compat_get_qcedev_sha_op_req(
for (i = 0; i < QCEDEV_MAX_BUFFERS; i++) {
err |= get_user(vaddr, &data32->data[i].vaddr);
- data->data[i].vaddr = 0;
err |= put_user(vaddr, (compat_uptr_t *)&data->data[i].vaddr);
err |= get_user(len, &data32->data[i].len);
err |= put_user(len, &data->data[i].len);
@@ -295,7 +290,6 @@ static int compat_get_qcedev_sha_op_req(
err |= get_user(diglen, &data32->diglen);
err |= put_user(diglen, &data->diglen);
err |= get_user(authkey, &data32->authkey);
- data->authkey = NULL;
err |= put_user(authkey, (compat_uptr_t *)&data->authkey);
err |= get_user(authklen, &data32->authklen);
err |= put_user(authklen, &data->authklen);
@@ -322,7 +316,6 @@ static int compat_put_qcedev_sha_op_req(
for (i = 0; i < QCEDEV_MAX_BUFFERS; i++) {
err |= get_user(vaddr, (compat_uptr_t *)&data->data[i].vaddr);
- data32->data[i].vaddr = 0;
err |= put_user(vaddr, &data32->data[i].vaddr);
err |= get_user(len, &data->data[i].len);
err |= put_user(len, &data32->data[i].len);
@@ -341,7 +334,6 @@ static int compat_put_qcedev_sha_op_req(
err |= get_user(diglen, &data->diglen);
err |= put_user(diglen, &data32->diglen);
err |= get_user(authkey, (compat_uptr_t *)&data->authkey);
- data32->authkey = 0;
err |= put_user(authkey, &data32->authkey);
err |= get_user(authklen, &data->authklen);
err |= put_user(authklen, &data32->authklen);
diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c
index bbdde2206c7..db0925b8f3f 100644
--- a/drivers/crypto/msm/qce50.c
+++ b/drivers/crypto/msm/qce50.c
@@ -2061,6 +2061,10 @@ static int _sha_complete(struct qce_device *pce_dev)
uint32_t result_dump_status;
areq = (struct ahash_request *) pce_dev->areq;
+ if (!areq) {
+ pr_err("sha operation error. areq is NULL\n");
+ return -ENXIO;
+ }
qce_dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
DMA_TO_DEVICE);
memcpy(digest, (char *)(&pce_dev->ce_sps.result->auth_iv[0]),
@@ -5513,6 +5517,5 @@ int qce_hw_support(void *handle, struct ce_hw_support *ce_support)
}
EXPORT_SYMBOL(qce_hw_support);
-
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Crypto Engine driver");
diff --git a/drivers/crypto/msm/qcrypto.c b/drivers/crypto/msm/qcrypto.c
index f670d2d58c2..9b093294439 100644
--- a/drivers/crypto/msm/qcrypto.c
+++ b/drivers/crypto/msm/qcrypto.c
@@ -3613,6 +3613,7 @@ static int _sha1_hmac_setkey(struct crypto_ahash *tfm, const u8 *key,
unsigned int len)
{
struct qcrypto_sha_ctx *sha_ctx = crypto_tfm_ctx(&tfm->base);
+ int ret = 0;
memset(&sha_ctx->authkey[0], 0, SHA1_BLOCK_SIZE);
if (len <= SHA1_BLOCK_SIZE) {
memcpy(&sha_ctx->authkey[0], key, len);
@@ -3620,16 +3621,19 @@ static int _sha1_hmac_setkey(struct crypto_ahash *tfm, const u8 *key,
} else {
sha_ctx->alg = QCE_HASH_SHA1;
sha_ctx->diglen = SHA1_DIGEST_SIZE;
- _sha_hmac_setkey(tfm, key, len);
+ ret = _sha_hmac_setkey(tfm, key, len);
+ if (ret)
+ pr_err("SHA1 hmac setkey failed\n");
sha_ctx->authkey_in_len = SHA1_BLOCK_SIZE;
}
- return 0;
+ return ret;
}
static int _sha256_hmac_setkey(struct crypto_ahash *tfm, const u8 *key,
unsigned int len)
{
struct qcrypto_sha_ctx *sha_ctx = crypto_tfm_ctx(&tfm->base);
+ int ret = 0;
memset(&sha_ctx->authkey[0], 0, SHA256_BLOCK_SIZE);
if (len <= SHA256_BLOCK_SIZE) {
@@ -3638,11 +3642,13 @@ static int _sha256_hmac_setkey(struct crypto_ahash *tfm, const u8 *key,
} else {
sha_ctx->alg = QCE_HASH_SHA256;
sha_ctx->diglen = SHA256_DIGEST_SIZE;
- _sha_hmac_setkey(tfm, key, len);
+ ret = _sha_hmac_setkey(tfm, key, len);
+ if (ret)
+ pr_err("SHA256 hmac setkey failed\n");
sha_ctx->authkey_in_len = SHA256_BLOCK_SIZE;
}
- return 0;
+ return ret;
}
static int _sha_hmac_init_ihash(struct ahash_request *req,
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 057d894eee6..6e5ba44dfaa 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -623,7 +623,7 @@ static void talitos_unregister_rng(struct device *dev)
* crypto alg
*/
#define TALITOS_CRA_PRIORITY 3000
-#define TALITOS_MAX_KEY_SIZE 96
+#define TALITOS_MAX_KEY_SIZE (AES_MAX_KEY_SIZE + SHA512_BLOCK_SIZE)
#define TALITOS_MAX_IV_LENGTH 16 /* max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */
#define MD5_BLOCK_SIZE 64
@@ -1380,6 +1380,11 @@ static int ablkcipher_setkey(struct crypto_ablkcipher *cipher,
{
struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+ if (keylen > TALITOS_MAX_KEY_SIZE) {
+ crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
+ return -EINVAL;
+ }
+
memcpy(&ctx->key, key, keylen);
ctx->keylen = keylen;
diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index 7816b923857..a4d9c6a7aac 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -79,15 +79,6 @@ config DEVFREQ_GOV_MSM_ADRENO_TZ
Sets the frequency using a "on-demand" algorithm.
This governor is unlikely to be useful for other devices.
-config ADRENO_IDLER
- tristate "MSM Adreno idler"
- depends on DEVFREQ_GOV_MSM_ADRENO_TZ
- help
- Uses a different calculation method on top of Adreno TZ
- just for calculating frequency for idle to reduce the
- wasted power coming from stock Adreno TZ while
- maintaining high-performance.
-
config MSM_BIMC_BWMON
tristate "MSM BIMC Bandwidth monitor hardware"
depends on ARCH_MSM
diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
index 7fd3d000af1..97b550b08dc 100644
--- a/drivers/devfreq/Makefile
+++ b/drivers/devfreq/Makefile
@@ -8,7 +8,6 @@ obj-$(CONFIG_DEVFREQ_GOV_POWERSAVE) += governor_powersave.o
obj-$(CONFIG_DEVFREQ_GOV_USERSPACE) += governor_userspace.o
obj-$(CONFIG_DEVFREQ_GOV_CPUFREQ) += governor_cpufreq.o
obj-$(CONFIG_DEVFREQ_GOV_MSM_ADRENO_TZ) += governor_msm_adreno_tz.o
-obj-$(CONFIG_ADRENO_IDLER) += adreno_idler.o
obj-$(CONFIG_DEVFREQ_GOV_MSM_CPUFREQ) += governor_msm_cpufreq.o
obj-$(CONFIG_ARCH_MSM_KRAIT) += krait-l2pm.o
obj-$(CONFIG_MSM_BIMC_BWMON) += bimc-bwmon.o
diff --git a/drivers/devfreq/adreno_idler.c b/drivers/devfreq/adreno_idler.c
deleted file mode 100644
index 0e6cd27b1b1..00000000000
--- a/drivers/devfreq/adreno_idler.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Author: Park Ju Hyung aka arter97 <qkrwngud825@gmail.com>
- *
- * Copyright 2015 Park Ju Hyung
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-/*
- * Adreno idler - Idling algorithm,
- * an efficient workaround for msm-adreno-tz's overheads.
- *
- * Main goal is to lower the power consumptions while maintaining high-performance.
- *
- * Since msm-adreno-tz tends to *not* use the lowest frequency even on idle,
- * Adreno idler replaces msm-adreno-tz's algorithm when it comes to
- * calculating idle frequency(mostly by ondemand's method).
- * The higher frequencies are not touched with this algorithm, so high-demanding
- * games will (most likely) not suffer from worsened performance.
- */
-
-#include <linux/module.h>
-#include <linux/devfreq.h>
-#include <linux/msm_adreno_devfreq.h>
-
-#define ADRENO_IDLER_MAJOR_VERSION 1
-#define ADRENO_IDLER_MINOR_VERSION 1
-
-/* stats.busy_time threshold for determining if the given workload is idle.
- Any workload higher than this will be treated as a non-idle workload.
- Adreno idler will more actively try to ramp down the frequency
- if this is set to a higher value. */
-static unsigned long idleworkload = 5000;
-module_param_named(adreno_idler_idleworkload, idleworkload, ulong, 0664);
-
-/* Number of events to wait before ramping down the frequency.
- The idlewait'th events before current one must be all idle before
- Adreno idler ramps down the frequency.
- This implementation is to prevent micro-lags on scrolling or playing games.
- Adreno idler will more actively try to ramp down the frequency
- if this is set to a lower value. */
-static unsigned int idlewait = 20;
-module_param_named(adreno_idler_idlewait, idlewait, uint, 0664);
-
-/* Taken from ondemand */
-static unsigned int downdifferential = 20;
-module_param_named(adreno_idler_downdifferential, downdifferential, uint, 0664);
-
-/* Master switch to activate the whole routine */
-static bool adreno_idler_active = true;
-module_param_named(adreno_idler_active, adreno_idler_active, bool, 0664);
-
-static unsigned int idlecount = 0;
-
-int adreno_idler(struct devfreq_dev_status stats, struct devfreq *devfreq,
- unsigned long *freq)
-{
- if (!adreno_idler_active)
- return 0;
-
- if (stats.busy_time < idleworkload) {
- /* busy_time >= idleworkload should be considered as a non-idle workload. */
- idlecount++;
- if (*freq == devfreq->profile->freq_table[devfreq->profile->max_state - 1]) {
- /* Frequency is already at its lowest.
- No need to calculate things, so bail out. */
- return 1;
- }
- if (idlecount >= idlewait &&
- stats.busy_time * 100 < stats.total_time * downdifferential) {
- /* We are idle for (idlewait + 1)'th time! Ramp down the frequency now. */
- *freq = devfreq->profile->freq_table[devfreq->profile->max_state - 1];
- idlecount--;
- return 1;
- }
- } else {
- idlecount = 0;
- /* Do not return 1 here and allow rest of the algorithm to
- figure out the appropriate frequency for current workload.
- It can even set it back to the lowest frequency. */
- }
- return 0;
-}
-EXPORT_SYMBOL(adreno_idler);
-
-static int __init adreno_idler_init(void)
-{
- pr_info("adreno_idler: version %d.%d by arter97\n",
- ADRENO_IDLER_MAJOR_VERSION,
- ADRENO_IDLER_MINOR_VERSION);
-
- return 0;
-}
-subsys_initcall(adreno_idler_init);
-
-static void __exit adreno_idler_exit(void)
-{
- return;
-}
-module_exit(adreno_idler_exit);
-
-MODULE_AUTHOR("Park Ju Hyung <qkrwngud825@gmail.com>");
-MODULE_DESCRIPTION("'adreno_idler - A powersaver for Adreno TZ"
- "Control idle algorithm for Adreno GPU series");
-MODULE_LICENSE("GPL");
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index a5b09deba52..582b4d31c46 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -349,6 +349,7 @@ void devfreq_interval_update(struct devfreq *devfreq, unsigned int *delay)
unsigned int new_delay = *delay;
mutex_lock(&devfreq->lock);
+ devfreq->profile->polling_ms = new_delay;
if (devfreq->stop_polling)
goto out;
@@ -825,7 +826,6 @@ static ssize_t store_polling_interval(struct device *dev,
if (ret != 1)
return -EINVAL;
- df->profile->polling_ms = value;
df->governor->event_handler(df, DEVFREQ_GOV_INTERVAL, &value);
ret = count;
@@ -977,26 +977,6 @@ static ssize_t show_trans_table(struct device *dev, struct device_attribute *att
return len;
}
-static ssize_t show_time_in_state(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct devfreq *devfreq = to_devfreq(dev);
-
- ssize_t len = 0;
- int i, err;
- unsigned int max_state = devfreq->profile->max_state;
-
- err = devfreq_update_status(devfreq, devfreq->previous_freq);
- if (err)
- return 0;
-
- for (i = 0; i < max_state; i++) {
- len += sprintf(buf + len, "%u %u\n", devfreq->profile->freq_table[i],
- jiffies_to_msecs(devfreq->time_in_state[i]));
- }
- return len;
-}
-
static struct device_attribute devfreq_attrs[] = {
__ATTR(governor, S_IRUGO | S_IWUSR, show_governor, store_governor),
__ATTR(available_governors, S_IRUGO, show_available_governors, NULL),
@@ -1008,7 +988,6 @@ static struct device_attribute devfreq_attrs[] = {
__ATTR(min_freq, S_IRUGO | S_IWUSR, show_min_freq, store_min_freq),
__ATTR(max_freq, S_IRUGO | S_IWUSR, show_max_freq, store_max_freq),
__ATTR(trans_stat, S_IRUGO, show_trans_table, NULL),
- __ATTR(time_in_state, S_IRUGO, show_time_in_state, NULL),
{ },
};
@@ -1020,10 +999,7 @@ static int __init devfreq_init(void)
return PTR_ERR(devfreq_class);
}
- devfreq_wq =
- alloc_workqueue("devfreq_wq",
- WQ_HIGHPRI | WQ_UNBOUND | WQ_FREEZABLE |
- WQ_MEM_RECLAIM, 0);
+ devfreq_wq = create_freezable_workqueue("devfreq_wq");
if (IS_ERR(devfreq_wq)) {
class_destroy(devfreq_class);
pr_err("%s: couldn't create workqueue\n", __FILE__);
diff --git a/drivers/devfreq/governor_gpubw_mon.c b/drivers/devfreq/governor_gpubw_mon.c
index 1e78c8649d5..ff4a67ace9e 100644
--- a/drivers/devfreq/governor_gpubw_mon.c
+++ b/drivers/devfreq/governor_gpubw_mon.c
@@ -63,9 +63,6 @@ static int devfreq_gpubw_get_target(struct devfreq *df,
int norm_ab;
unsigned long ab_mbytes = 0;
- if (priv == NULL)
- return 0;
-
stats.private_data = &b;
result = df->profile->get_dev_status(df->dev.parent, &stats);
diff --git a/drivers/devfreq/governor_msm_adreno_tz.c b/drivers/devfreq/governor_msm_adreno_tz.c
index e6b8bb457b9..d68ae652c88 100644
--- a/drivers/devfreq/governor_msm_adreno_tz.c
+++ b/drivers/devfreq/governor_msm_adreno_tz.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -25,8 +25,7 @@
#include "governor.h"
static DEFINE_SPINLOCK(tz_lock);
-static DEFINE_SPINLOCK(sample_lock);
-static DEFINE_SPINLOCK(suspend_lock);
+
/*
* FLOOR is 5msec to capture up to 3 re-draws
* per frame for 60fps content.
@@ -63,115 +62,18 @@ static DEFINE_SPINLOCK(suspend_lock);
#define TAG "msm_adreno_tz: "
-static u64 suspend_time;
-static u64 suspend_start;
-static unsigned long acc_total, acc_relative_busy;
-
-static struct msm_adreno_extended_profile *partner_gpu_profile;
+struct msm_adreno_extended_profile *partner_gpu_profile;
static void do_partner_start_event(struct work_struct *work);
static void do_partner_stop_event(struct work_struct *work);
static void do_partner_suspend_event(struct work_struct *work);
static void do_partner_resume_event(struct work_struct *work);
-static struct workqueue_struct *workqueue;
-
-/*
- * Returns GPU suspend time in millisecond.
- */
-u64 suspend_time_ms(void)
-{
- u64 suspend_sampling_time;
- u64 time_diff = 0;
-
- if (suspend_start == 0)
- return 0;
-
- suspend_sampling_time = (u64)ktime_to_ms(ktime_get());
- time_diff = suspend_sampling_time - suspend_start;
- /* Update the suspend_start sample again */
- suspend_start = suspend_sampling_time;
- return time_diff;
-}
-
-static ssize_t gpu_load_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- unsigned long sysfs_busy_perc;
- /*
- * Average out the samples taken since last read
- * This will keep the average value in sync with
- * with the client sampling duration.
- */
- spin_lock(&sample_lock);
- sysfs_busy_perc = (acc_relative_busy * 100) / acc_total;
-
- /* Reset the parameters */
- acc_total = 0;
- acc_relative_busy = 0;
- spin_unlock(&sample_lock);
- return snprintf(buf, PAGE_SIZE, "%lu\n", sysfs_busy_perc);
-}
-
-/*
- * Returns the time in ms for which gpu was in suspend state
- * since last time the entry is read.
- */
-static ssize_t suspend_time_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- u64 time_diff = 0;
-
- spin_lock(&suspend_lock);
- time_diff = suspend_time_ms();
- /*
- * Adding the previous suspend time also as the gpu
- * can go and come out of suspend states in between
- * reads also and we should have the total suspend
- * since last read.
- */
- time_diff += suspend_time;
- suspend_time = 0;
- spin_unlock(&suspend_lock);
-
- return snprintf(buf, PAGE_SIZE, "%llu\n", time_diff);
-}
-
-static DEVICE_ATTR(gpu_load, 0444, gpu_load_show, NULL);
-
-static DEVICE_ATTR(suspend_time, 0444,
- suspend_time_show,
- NULL);
-
-static const struct device_attribute *adreno_tz_attr_list[] = {
- &dev_attr_gpu_load,
- &dev_attr_suspend_time,
- NULL
-};
-
-void compute_work_load(struct devfreq_dev_status *stats,
- struct devfreq_msm_adreno_tz_data *priv,
- struct devfreq *devfreq)
-{
- spin_lock(&sample_lock);
- /*
- * Keep collecting the stats till the client
- * reads it. Average of all samples and reset
- * is done when the entry is read
- */
- acc_total += stats->total_time;
- acc_relative_busy += (stats->busy_time * stats->current_frequency) /
- devfreq->profile->freq_table[0];
- spin_unlock(&sample_lock);
-}
-
/* Trap into the TrustZone, and call funcs there. */
static int __secure_tz_reset_entry2(unsigned int *scm_data, u32 size_scm_data,
bool is_64)
{
int ret;
- /* sync memory before sending the commands to tz */
+ /* sync memory before sending the commands to tz*/
__iowmb();
if (!is_64) {
@@ -197,7 +99,7 @@ static int __secure_tz_update_entry3(unsigned int *scm_data, u32 size_scm_data,
int *val, u32 size_val, bool is_64)
{
int ret;
- /* sync memory before sending the commands to tz */
+ /* sync memory before sending the commands to tz*/
__iowmb();
if (!is_64) {
@@ -274,10 +176,6 @@ static int tz_init(struct devfreq_msm_adreno_tz_data *priv,
return ret;
}
-#ifdef CONFIG_ADRENO_IDLER
-extern int adreno_idler(struct devfreq_dev_status stats, struct devfreq *devfreq,
- unsigned long *freq);
-#endif
static int tz_get_target_freq(struct devfreq *devfreq, unsigned long *freq,
u32 *flag)
{
@@ -295,27 +193,10 @@ static int tz_get_target_freq(struct devfreq *devfreq, unsigned long *freq,
return result;
}
- /* Prevent overflow */
- if (stats.busy_time >= (1 << 24) || stats.total_time >= (1 << 24)) {
- stats.busy_time >>= 7;
- stats.total_time >>= 7;
- }
-
*freq = stats.current_frequency;
- *flag = 0;
-
-#ifdef CONFIG_ADRENO_IDLER
- if (adreno_idler(stats, devfreq, freq)) {
- /* adreno_idler has asked to bail out now */
- return 0;
- }
-#endif
-
priv->bin.total_time += stats.total_time;
priv->bin.busy_time += stats.busy_time;
- /* Update the GPU load statistics */
- compute_work_load(&stats, priv, devfreq);
/*
* Do not waste CPU cycles running this algorithm if
* the GPU just started, or if less than FLOOR time
@@ -437,6 +318,8 @@ static int tz_start(struct devfreq *devfreq)
return -EINVAL;
}
+ gpu_profile->partner_wq = create_freezable_workqueue
+ ("governor_msm_adreno_tz_wq");
INIT_WORK(&gpu_profile->partner_start_event_ws,
do_partner_start_event);
INIT_WORK(&gpu_profile->partner_stop_event_ws,
@@ -453,23 +336,21 @@ static int tz_start(struct devfreq *devfreq)
return ret;
}
- for (i = 0; adreno_tz_attr_list[i] != NULL; i++)
- device_create_file(&devfreq->dev, adreno_tz_attr_list[i]);
-
return kgsl_devfreq_add_notifier(devfreq->dev.parent, &priv->nb);
}
static int tz_stop(struct devfreq *devfreq)
{
- int i;
struct devfreq_msm_adreno_tz_data *priv = devfreq->data;
+ struct msm_adreno_extended_profile *gpu_profile = container_of(
+ (devfreq->profile),
+ struct msm_adreno_extended_profile,
+ profile);
kgsl_devfreq_del_notifier(devfreq->dev.parent, &priv->nb);
- for (i = 0; adreno_tz_attr_list[i] != NULL; i++)
- device_remove_file(&devfreq->dev, adreno_tz_attr_list[i]);
-
- flush_workqueue(workqueue);
+ flush_workqueue(gpu_profile->partner_wq);
+ destroy_workqueue(gpu_profile->partner_wq);
/* leaving the governor and cleaning the pointer to private data */
devfreq->data = NULL;
@@ -491,7 +372,6 @@ static int tz_suspend(struct devfreq *devfreq)
static int tz_handler(struct devfreq *devfreq, unsigned int event, void *data)
{
int result;
-
struct msm_adreno_extended_profile *gpu_profile = container_of(
(devfreq->profile),
struct msm_adreno_extended_profile,
@@ -504,33 +384,14 @@ static int tz_handler(struct devfreq *devfreq, unsigned int event, void *data)
break;
case DEVFREQ_GOV_STOP:
- /* Queue the stop work before the TZ is stopped */
- if (partner_gpu_profile && partner_gpu_profile->bus_devfreq)
- queue_work(workqueue,
- &gpu_profile->partner_stop_event_ws);
- spin_lock(&suspend_lock);
- suspend_start = 0;
- spin_unlock(&suspend_lock);
result = tz_stop(devfreq);
break;
case DEVFREQ_GOV_SUSPEND:
result = tz_suspend(devfreq);
- if (!result) {
- spin_lock(&suspend_lock);
- /* Collect the start sample for suspend time */
- suspend_start = (u64)ktime_to_ms(ktime_get());
- spin_unlock(&suspend_lock);
- }
break;
case DEVFREQ_GOV_RESUME:
- spin_lock(&suspend_lock);
- suspend_time += suspend_time_ms();
- /* Reset the suspend_start when gpu resumes */
- suspend_start = 0;
- spin_unlock(&suspend_lock);
-
case DEVFREQ_GOV_INTERVAL:
/* ignored, this governor doesn't use polling */
default:
@@ -541,15 +402,19 @@ static int tz_handler(struct devfreq *devfreq, unsigned int event, void *data)
if (partner_gpu_profile && partner_gpu_profile->bus_devfreq)
switch (event) {
case DEVFREQ_GOV_START:
- queue_work(workqueue,
+ queue_work(gpu_profile->partner_wq,
&gpu_profile->partner_start_event_ws);
break;
+ case DEVFREQ_GOV_STOP:
+ queue_work(gpu_profile->partner_wq,
+ &gpu_profile->partner_stop_event_ws);
+ break;
case DEVFREQ_GOV_SUSPEND:
- queue_work(workqueue,
+ queue_work(gpu_profile->partner_wq,
&gpu_profile->partner_suspend_event_ws);
break;
case DEVFREQ_GOV_RESUME:
- queue_work(workqueue,
+ queue_work(gpu_profile->partner_wq,
&gpu_profile->partner_resume_event_ws);
break;
}
@@ -559,16 +424,9 @@ static int tz_handler(struct devfreq *devfreq, unsigned int event, void *data)
static void _do_partner_event(struct work_struct *work, unsigned int event)
{
- struct devfreq *bus_devfreq;
-
- if (partner_gpu_profile == NULL)
- return;
+ struct devfreq *bus_devfreq = partner_gpu_profile->bus_devfreq;
- bus_devfreq = partner_gpu_profile->bus_devfreq;
-
- if (bus_devfreq != NULL &&
- bus_devfreq->governor &&
- bus_devfreq->governor->event_handler)
+ if (bus_devfreq->governor && bus_devfreq->governor->event_handler)
bus_devfreq->governor->event_handler(bus_devfreq, event, NULL);
}
@@ -601,22 +459,18 @@ static struct devfreq_governor msm_adreno_tz = {
static int __init msm_adreno_tz_init(void)
{
- workqueue = create_freezable_workqueue("governor_msm_adreno_tz_wq");
- if (workqueue == NULL)
- return -ENOMEM;
-
return devfreq_add_governor(&msm_adreno_tz);
}
subsys_initcall(msm_adreno_tz_init);
static void __exit msm_adreno_tz_exit(void)
{
- int ret = devfreq_remove_governor(&msm_adreno_tz);
+ int ret;
+ ret = devfreq_remove_governor(&msm_adreno_tz);
if (ret)
pr_err(TAG "failed to remove governor %d\n", ret);
- if (workqueue != NULL)
- destroy_workqueue(workqueue);
+ return;
}
module_exit(msm_adreno_tz_exit);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c
index 89664933861..a3a70283bde 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c
@@ -368,6 +368,8 @@ void *vmw_fifo_reserve(struct vmw_private *dev_priv, uint32_t bytes)
return fifo_state->static_buffer;
else {
fifo_state->dynamic_buffer = vmalloc(bytes);
+ if (!fifo_state->dynamic_buffer)
+ goto out_err;
return fifo_state->dynamic_buffer;
}
}
diff --git a/drivers/gpu/msm/adreno_a4xx.c b/drivers/gpu/msm/adreno_a4xx.c
index cad2fff34dd..01bf2415254 100644
--- a/drivers/gpu/msm/adreno_a4xx.c
+++ b/drivers/gpu/msm/adreno_a4xx.c
@@ -551,10 +551,6 @@ static void a4xx_enable_hwcg(struct kgsl_device *device)
kgsl_regwrite(device, A4XX_RBBM_CLOCK_CTL, 0);
else
kgsl_regwrite(device, A4XX_RBBM_CLOCK_CTL, 0xAAAAAAAA);
-
- /* MMI_STOPSHIP: Disable HW clock gating in all GPU blocks */
- kgsl_regwrite(device, A4XX_RBBM_CLOCK_CTL, 0);
-
kgsl_regwrite(device, A4XX_RBBM_CLOCK_CTL2, 0);
}
diff --git a/drivers/gpu/msm/kgsl_cmdbatch.c b/drivers/gpu/msm/kgsl_cmdbatch.c
index 7dfd691d84c..065686a2a49 100644
--- a/drivers/gpu/msm/kgsl_cmdbatch.c
+++ b/drivers/gpu/msm/kgsl_cmdbatch.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2008-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -107,6 +107,7 @@ static void _kgsl_cmdbatch_timer(unsigned long data)
struct kgsl_device *device;
struct kgsl_cmdbatch *cmdbatch = (struct kgsl_cmdbatch *) data;
struct kgsl_cmdbatch_sync_event *event;
+ unsigned long flags;
if (cmdbatch == NULL || cmdbatch->context == NULL)
return;
@@ -121,14 +122,14 @@ static void _kgsl_cmdbatch_timer(unsigned long data)
kgsl_context_dump(cmdbatch->context);
clear_bit(CMDBATCH_FLAG_FENCE_LOG, &cmdbatch->priv);
- spin_lock(&cmdbatch->lock);
+ spin_lock_irqsave(&cmdbatch->lock, flags);
/* Print all the fences */
list_for_each_entry(event, &cmdbatch->synclist, node) {
if (KGSL_CMD_SYNCPOINT_TYPE_FENCE == event->type &&
event->handle && event->handle->fence)
kgsl_sync_fence_log(event->handle->fence);
}
- spin_unlock(&cmdbatch->lock);
+ spin_unlock_irqrestore(&cmdbatch->lock, flags);
dev_err(device->dev, "--gpu syncpoint deadlock print end--\n");
}
@@ -184,15 +185,15 @@ static void kgsl_cmdbatch_sync_expire(struct kgsl_device *device,
struct kgsl_cmdbatch_sync_event *event)
{
struct kgsl_cmdbatch_sync_event *e, *tmp;
+ unsigned long flags;
int sched = 0;
int removed = 0;
/*
- * We may have cmdbatch timer running, which also uses same lock,
- * take a lock with software interrupt disabled (bh) to avoid
- * spin lock recursion.
+ * cmdbatch timer or event callback might run at this time in interrupt
+ * context and uses same lock. So use irq-save version of spin lock.
*/
- spin_lock_bh(&event->cmdbatch->lock);
+ spin_lock_irqsave(&event->cmdbatch->lock, flags);
/*
* sync events that are contained by a cmdbatch which has been
@@ -207,8 +208,9 @@ static void kgsl_cmdbatch_sync_expire(struct kgsl_device *device,
}
}
+ event->handle = NULL;
sched = list_empty(&event->cmdbatch->synclist) ? 1 : 0;
- spin_unlock_bh(&event->cmdbatch->lock);
+ spin_unlock_irqrestore(&event->cmdbatch->lock, flags);
/* If the list is empty delete the canary timer */
if (sched)
@@ -269,19 +271,22 @@ void kgsl_cmdbatch_destroy(struct kgsl_cmdbatch *cmdbatch)
struct kgsl_cmdbatch_sync_event *event, *tmpsync;
LIST_HEAD(cancel_synclist);
int sched = 0;
-
+ unsigned long flags;
if (IS_ERR_OR_NULL(cmdbatch))
return;
/* Zap the canary timer */
del_timer_sync(&cmdbatch->timer);
- /* non-bh because we just destroyed timer */
- spin_lock(&cmdbatch->lock);
+ /*
+ * callback might run in interrupt context
+ * so need to use irqsave version of spinlocks.
+ */
+ spin_lock_irqsave(&cmdbatch->lock, flags);
/* Empty the synclist before canceling events */
list_splice_init(&cmdbatch->synclist, &cancel_synclist);
- spin_unlock(&cmdbatch->lock);
+ spin_unlock_irqrestore(&cmdbatch->lock, flags);
/*
* Finish canceling events outside the cmdbatch spinlock and
@@ -303,8 +308,15 @@ void kgsl_cmdbatch_destroy(struct kgsl_cmdbatch *cmdbatch)
kgsl_cmdbatch_sync_func, event);
} else if (event->type == KGSL_CMD_SYNCPOINT_TYPE_FENCE) {
/* Put events that are successfully canceled */
- if (kgsl_sync_fence_async_cancel(event->handle))
+ spin_lock_irqsave(&cmdbatch->lock, flags);
+
+ if (kgsl_sync_fence_async_cancel(event->handle)) {
+ event->handle = NULL;
+ spin_unlock_irqrestore(&cmdbatch->lock, flags);
kgsl_cmdbatch_sync_event_put(event);
+ } else {
+ spin_unlock_irqrestore(&cmdbatch->lock, flags);
+ }
}
/* Put events that have been removed from the synclist */
@@ -365,7 +377,7 @@ static int kgsl_cmdbatch_add_sync_fence(struct kgsl_device *device,
{
struct kgsl_cmd_syncpoint_fence *sync = priv;
struct kgsl_cmdbatch_sync_event *event;
-
+ unsigned long flags;
event = kzalloc(sizeof(*event), GFP_KERNEL);
if (event == NULL)
return -ENOMEM;
@@ -392,11 +404,6 @@ static int kgsl_cmdbatch_add_sync_fence(struct kgsl_device *device,
kref_get(&event->refcount);
- /* non-bh because, we haven't started cmdbatch timer yet */
- spin_lock(&cmdbatch->lock);
- list_add(&event->node, &cmdbatch->synclist);
- spin_unlock(&cmdbatch->lock);
-
/*
* Increment the reference count for the async callback.
* Decrement when the callback is successfully canceled, when
@@ -404,6 +411,10 @@ static int kgsl_cmdbatch_add_sync_fence(struct kgsl_device *device,
*/
kref_get(&event->refcount);
+
+ spin_lock_irqsave(&cmdbatch->lock, flags);
+ list_add(&event->node, &cmdbatch->synclist);
+
event->handle = kgsl_sync_fence_async_wait(sync->fd,
kgsl_cmdbatch_sync_fence_func, event);
@@ -411,17 +422,14 @@ static int kgsl_cmdbatch_add_sync_fence(struct kgsl_device *device,
int ret = PTR_ERR(event->handle);
event->handle = NULL;
-
- /* Failed to add the event to the async callback */
- kgsl_cmdbatch_sync_event_put(event);
-
/* Remove event from the synclist */
- spin_lock(&cmdbatch->lock);
list_del(&event->node);
- spin_unlock(&cmdbatch->lock);
+ spin_unlock_irqrestore(&cmdbatch->lock, flags);
+ /* Put for event removal from the synclist */
kgsl_cmdbatch_sync_event_put(event);
-
- /* Event no longer needed by this function */
+ /* Unable to add event to the async callback so a put */
+ kgsl_cmdbatch_sync_event_put(event);
+ /* Put since event no longer needed by this function */
kgsl_cmdbatch_sync_event_put(event);
/*
@@ -435,6 +443,7 @@ static int kgsl_cmdbatch_add_sync_fence(struct kgsl_device *device,
}
trace_syncpoint_fence(cmdbatch, event->handle->name);
+ spin_unlock_irqrestore(&cmdbatch->lock, flags);
/*
* Event was successfully added to the synclist, the async
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 343d9339fe1..7bf7469e2b7 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -791,19 +791,12 @@ static ssize_t kgsl_pwrctrl_gpuclk_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- unsigned long freq;
struct kgsl_device *device = kgsl_device_from_dev(dev);
struct kgsl_pwrctrl *pwr;
if (device == NULL)
return 0;
pwr = &device->pwrctrl;
-
- if (device->state == KGSL_STATE_SLUMBER)
- freq = pwr->pwrlevels[pwr->num_pwrlevels - 1].gpu_freq;
- else
- freq = kgsl_pwrctrl_active_freq(pwr);
-
- return snprintf(buf, PAGE_SIZE, "%lu\n", freq);
+ return snprintf(buf, PAGE_SIZE, "%ld\n", kgsl_pwrctrl_active_freq(pwr));
}
static ssize_t kgsl_pwrctrl_idle_timer_store(struct device *dev,
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index 700145b1508..602f1637317 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -510,17 +510,18 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd,
goto inval;
field = report->field[uref->field_index];
+ }
- if (cmd == HIDIOCGCOLLECTIONINDEX) {
- if (uref->usage_index >= field->maxusage)
- goto inval;
- } else if (uref->usage_index >= field->report_count)
+ if (cmd == HIDIOCGCOLLECTIONINDEX) {
+ if (uref->usage_index >= field->maxusage)
goto inval;
- }
+ } else if (uref->usage_index >= field->report_count)
+ goto inval;
- if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) &&
- (uref_multi->num_values > HID_MAX_MULTI_USAGES ||
- uref->usage_index + uref_multi->num_values > field->report_count))
+ else if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) &&
+ (uref_multi->num_values > HID_MAX_MULTI_USAGES ||
+ uref->usage_index + uref_multi->num_values >
+ field->report_count))
goto inval;
switch (cmd) {
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 9d539cbfc83..c0e4143bee9 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -1323,6 +1323,7 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
/* add the driver to the list of i2c drivers in the driver core */
driver->driver.owner = owner;
driver->driver.bus = &i2c_bus_type;
+ INIT_LIST_HEAD(&driver->clients);
/* When registration returns, the driver core
* will have called probe() for all matching-but-unbound devices.
@@ -1341,7 +1342,6 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);
- INIT_LIST_HEAD(&driver->clients);
/* Walk the adapters that are already present */
i2c_for_each_dev(driver, __process_new_driver);
diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c
index 5f5f20f4223..c61f3e7aa35 100644
--- a/drivers/infiniband/hw/qib/qib_iba7322.c
+++ b/drivers/infiniband/hw/qib/qib_iba7322.c
@@ -6670,7 +6670,7 @@ static void qib_7322_txchk_change(struct qib_devdata *dd, u32 start,
unsigned long flags;
while (wait) {
- unsigned long shadow;
+ unsigned long shadow = 0;
int cstart, previ = -1;
/*
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
index 8292554bccb..7604ae54d7b 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
@@ -165,11 +165,11 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
out:
mutex_unlock(&ppriv->vlan_mutex);
+ rtnl_unlock();
+
if (result)
free_netdev(priv->dev);
- rtnl_unlock();
-
return result;
}
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 0734f1b0bdc..a0a6b5762cf 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -1200,9 +1200,6 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
struct usb_endpoint_descriptor *ep_irq_in;
int ep_irq_in_idx;
int i, error;
-
- if (intf->cur_altsetting->desc.bNumEndpoints != 2)
- return -ENODEV;
if (intf->cur_altsetting->desc.bNumEndpoints != 2)
return -ENODEV;
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index c9346bf6156..4f0d5a6cbd6 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -955,6 +955,16 @@ config TOUCHSCREEN_FT5X06_GESTURE
If unsure, say N.
+config TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_EXTRA_SYSFS
+ bool "Synaptics DSX firmware update extra sysfs attributes"
+ depends on TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE
+ help
+ Say Y here to enable support for extra sysfs attributes
+ supporting firmware update in a development environment.
+ This does not affect the core or other subsystem attributes.
+
+ If unsure, say N.
+
config TOUCHSCREEN_GEN_VKEYS
tristate "Touchscreen Virtual Keys Driver"
help
diff --git a/drivers/input/touchscreen/synaptics_fw_update.c b/drivers/input/touchscreen/synaptics_fw_update.c
index 409988fce55..cac9c7a29a1 100644
--- a/drivers/input/touchscreen/synaptics_fw_update.c
+++ b/drivers/input/touchscreen/synaptics_fw_update.c
@@ -1305,6 +1305,7 @@ write_config:
return retval;
}
+#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_EXTRA_SYSFS
static int fwu_start_write_config(void)
{
int retval;
@@ -1357,6 +1358,7 @@ static int fwu_start_write_config(void)
return retval;
}
+#endif
static int fwu_do_write_lockdown(bool reset)
{
@@ -1404,6 +1406,7 @@ exit:
return retval;
}
+#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_EXTRA_SYSFS
static int fwu_start_write_lockdown(void)
{
if (parse_header())
@@ -1507,6 +1510,7 @@ static int fwu_do_read_config(void)
exit:
return retval;
}
+#endif
static int fwu_do_reflash(void)
{
@@ -1732,6 +1736,7 @@ int synaptics_fw_updater(void)
}
EXPORT_SYMBOL(synaptics_fw_updater);
+#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_EXTRA_SYSFS
static ssize_t fwu_sysfs_show_image(struct file *data_file,
struct kobject *kobj, struct bin_attribute *attributes,
char *buf, loff_t pos, size_t count)
@@ -2155,6 +2160,7 @@ static ssize_t fwu_sysfs_package_id_show(struct device *dev,
(pkg_id[1] << 8) | pkg_id[0],
(pkg_id[3] << 8) | pkg_id[2]);
}
+#endif
static int synaptics_rmi4_debug_dump_info(struct seq_file *m, void *v)
{
@@ -2188,6 +2194,7 @@ static void synaptics_rmi4_fwu_attn(struct synaptics_rmi4_data *rmi4_data,
return;
}
+#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_EXTRA_SYSFS
static struct bin_attribute dev_attr_data = {
.attr = {
.name = "data",
@@ -2197,8 +2204,10 @@ static struct bin_attribute dev_attr_data = {
.read = fwu_sysfs_show_image,
.write = fwu_sysfs_store_image,
};
+#endif
static struct device_attribute attrs[] = {
+#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_EXTRA_SYSFS
__ATTR(fw_name, S_IRUGO | S_IWUSR | S_IWGRP,
fwu_sysfs_image_name_show,
fwu_sysfs_image_name_store),
@@ -2247,6 +2256,7 @@ static struct device_attribute attrs[] = {
__ATTR(package_id, S_IRUGO,
fwu_sysfs_package_id_show,
synaptics_rmi4_store_error),
+#endif
};
@@ -2332,6 +2342,29 @@ static int synaptics_rmi4_fwu_init(struct synaptics_rmi4_data *rmi4_data)
fwu->initialized = true;
fwu->polling_mode = false;
+#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_EXTRA_SYSFS
+ retval = sysfs_create_bin_file(&rmi4_data->i2c_client->dev.kobj,
+ &dev_attr_data);
+ if (retval < 0) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to create sysfs bin file\n",
+ __func__);
+ goto exit_free_mem;
+ }
+#endif
+
+ for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
+ retval = sysfs_create_file(&rmi4_data->i2c_client->dev.kobj,
+ &attrs[attr_count].attr);
+ if (retval < 0) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to create sysfs attributes\n",
+ __func__);
+ retval = -ENODEV;
+ goto exit_remove_attrs;
+ }
+ }
+
temp = debugfs_create_file("dump_info", S_IRUSR | S_IWUSR,
fwu->rmi4_data->dir, fwu->rmi4_data,
&debug_dump_info_fops);
@@ -2340,13 +2373,13 @@ static int synaptics_rmi4_fwu_init(struct synaptics_rmi4_data *rmi4_data)
"%s: Failed to create debugfs dump info file\n",
__func__);
retval = PTR_ERR(temp);
- goto exit_free_mem;
+ goto exit_remove_attrs;
}
fwu->ts_info = kzalloc(RMI4_INFO_MAX_LEN, GFP_KERNEL);
if (!fwu->ts_info) {
dev_err(&rmi4_data->i2c_client->dev, "Not enough memory\n");
- goto exit_free_debugfs;
+ goto exit_free_ts_info;
}
synaptics_rmi4_update_debug_info();
@@ -2358,41 +2391,20 @@ static int synaptics_rmi4_fwu_init(struct synaptics_rmi4_data *rmi4_data)
&fwu->fwu_work,
msecs_to_jiffies(1000));
#endif
- retval = sysfs_create_bin_file(&rmi4_data->i2c_client->dev.kobj,
- &dev_attr_data);
- if (retval < 0) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to create sysfs bin file\n",
- __func__);
- goto exit_free_ts_info;
- }
-
- for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
- retval = sysfs_create_file(&rmi4_data->i2c_client->dev.kobj,
- &attrs[attr_count].attr);
- if (retval < 0) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to create sysfs attributes\n",
- __func__);
- retval = -ENODEV;
- goto exit_remove_attrs;
- }
- }
return 0;
-
+exit_free_ts_info:
+ debugfs_remove(temp);
exit_remove_attrs:
for (attr_count--; attr_count >= 0; attr_count--) {
sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
&attrs[attr_count].attr);
}
+#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_EXTRA_SYSFS
sysfs_remove_bin_file(&rmi4_data->input_dev->dev.kobj, &dev_attr_data);
+#endif
-exit_free_ts_info:
- kfree(fwu->ts_info);
-exit_free_debugfs:
- debugfs_remove(temp);
exit_free_mem:
kfree(fwu->fn_ptr);
@@ -2408,7 +2420,9 @@ static void synaptics_rmi4_fwu_remove(struct synaptics_rmi4_data *rmi4_data)
{
unsigned char attr_count;
+#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_EXTRA_SYSFS
sysfs_remove_bin_file(&rmi4_data->input_dev->dev.kobj, &dev_attr_data);
+#endif
for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 2825a446df7..9a8b80094fb 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -3402,6 +3402,7 @@ static size_t amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova,
mutex_unlock(&domain->api_lock);
domain_flush_tlb_pde(domain);
+ domain_flush_complete(domain);
return unmap_size;
}
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 37470ee7c85..4d874427101 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -1806,6 +1806,11 @@ int bitmap_resize(struct bitmap *bitmap, sector_t blocks,
long pages;
struct bitmap_page *new_bp;
+ if (bitmap->storage.file && !init) {
+ pr_info("md: cannot resize file-based bitmap\n");
+ return -EINVAL;
+ }
+
if (chunksize == 0) {
/* If there is enough space, leave the chunk size unchanged,
* else increase by factor of two until there is enough space.
diff --git a/drivers/md/dm-android-verity.c b/drivers/md/dm-android-verity.c
index bb76926ab63..17cdfa8279d 100644
--- a/drivers/md/dm-android-verity.c
+++ b/drivers/md/dm-android-verity.c
@@ -576,15 +576,15 @@ static int add_as_linear_device(struct dm_target *ti, char *dev)
DM_LINEAR_TARGET_OFFSET};
int err = 0;
- android_verity_target.dtr = linear_target.dtr,
- android_verity_target.map = linear_target.map,
- android_verity_target.status = linear_target.status,
- android_verity_target.ioctl = linear_target.ioctl,
- android_verity_target.merge = linear_target.merge,
- android_verity_target.iterate_devices = linear_target.iterate_devices,
+ android_verity_target.dtr = dm_linear_dtr,
+ android_verity_target.map = dm_linear_map,
+ android_verity_target.status = dm_linear_status,
+ android_verity_target.ioctl = dm_linear_ioctl,
+ android_verity_target.merge = dm_linear_merge,
+ android_verity_target.iterate_devices = dm_linear_iterate_devices,
android_verity_target.io_hints = NULL;
- err = linear_target.ctr(ti, DM_LINEAR_ARGS, linear_table_args);
+ err = dm_linear_ctr(ti, DM_LINEAR_ARGS, linear_table_args);
if (!err) {
DMINFO("Added android-verity as a linear target");
diff --git a/drivers/md/dm-android-verity.h b/drivers/md/dm-android-verity.h
index fe53863c664..efb79652489 100644
--- a/drivers/md/dm-android-verity.h
+++ b/drivers/md/dm-android-verity.h
@@ -94,4 +94,16 @@ struct bio_read {
};
extern struct target_type linear_target;
+
+extern void dm_linear_dtr(struct dm_target *ti);
+extern int dm_linear_map(struct dm_target *ti, struct bio *bio);
+extern void dm_linear_status(struct dm_target *ti, status_type_t type,
+ unsigned status_flags, char *result, unsigned maxlen);
+extern int dm_linear_ioctl(struct dm_target *ti, unsigned int cmd,
+ unsigned long arg);
+extern int dm_linear_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
+ struct bio_vec *biovec, int max_size);
+extern int dm_linear_iterate_devices(struct dm_target *ti,
+ iterate_devices_callout_fn fn, void *data);
+extern int dm_linear_ctr(struct dm_target *ti, unsigned int argc, char **argv);
#endif /* DM_ANDROID_VERITY_H */
diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c
index 800286668ee..f63e07d3a77 100644
--- a/drivers/md/dm-linear.c
+++ b/drivers/md/dm-linear.c
@@ -25,7 +25,7 @@ struct linear_c {
/*
* Construct a linear mapping: <dev_path> <offset>
*/
-static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv)
+int dm_linear_ctr(struct dm_target *ti, unsigned int argc, char **argv)
{
struct linear_c *lc;
unsigned long long tmp;
@@ -64,7 +64,7 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv)
return -EINVAL;
}
-static void linear_dtr(struct dm_target *ti)
+void dm_linear_dtr(struct dm_target *ti)
{
struct linear_c *lc = (struct linear_c *) ti->private;
@@ -88,14 +88,14 @@ static void linear_map_bio(struct dm_target *ti, struct bio *bio)
bio->bi_sector = linear_map_sector(ti, bio->bi_sector);
}
-static int linear_map(struct dm_target *ti, struct bio *bio)
+int dm_linear_map(struct dm_target *ti, struct bio *bio)
{
linear_map_bio(ti, bio);
return DM_MAPIO_REMAPPED;
}
-static void linear_status(struct dm_target *ti, status_type_t type,
+void dm_linear_status(struct dm_target *ti, status_type_t type,
unsigned status_flags, char *result, unsigned maxlen)
{
struct linear_c *lc = (struct linear_c *) ti->private;
@@ -112,7 +112,7 @@ static void linear_status(struct dm_target *ti, status_type_t type,
}
}
-static int linear_ioctl(struct dm_target *ti, unsigned int cmd,
+int dm_linear_ioctl(struct dm_target *ti, unsigned int cmd,
unsigned long arg)
{
struct linear_c *lc = (struct linear_c *) ti->private;
@@ -129,7 +129,7 @@ static int linear_ioctl(struct dm_target *ti, unsigned int cmd,
return r ? : __blkdev_driver_ioctl(dev->bdev, dev->mode, cmd, arg);
}
-static int linear_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
+int dm_linear_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
struct bio_vec *biovec, int max_size)
{
struct linear_c *lc = ti->private;
@@ -144,7 +144,7 @@ static int linear_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
return min(max_size, q->merge_bvec_fn(q, bvm, biovec));
}
-static int linear_iterate_devices(struct dm_target *ti,
+int dm_linear_iterate_devices(struct dm_target *ti,
iterate_devices_callout_fn fn, void *data)
{
struct linear_c *lc = ti->private;
@@ -152,17 +152,17 @@ static int linear_iterate_devices(struct dm_target *ti,
return fn(ti, lc->dev, lc->start, ti->len, data);
}
-struct target_type linear_target = {
+static struct target_type linear_target = {
.name = "linear",
.version = {1, 2, 1},
.module = THIS_MODULE,
- .ctr = linear_ctr,
- .dtr = linear_dtr,
- .map = linear_map,
- .status = linear_status,
- .ioctl = linear_ioctl,
- .merge = linear_merge,
- .iterate_devices = linear_iterate_devices,
+ .ctr = dm_linear_ctr,
+ .dtr = dm_linear_dtr,
+ .map = dm_linear_map,
+ .status = dm_linear_status,
+ .ioctl = dm_linear_ioctl,
+ .merge = dm_linear_merge,
+ .iterate_devices = dm_linear_iterate_devices,
};
int __init dm_linear_init(void)
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 7c45286e266..95eb53f6841 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1898,7 +1898,7 @@ super_1_rdev_size_change(struct md_rdev *rdev, sector_t num_sectors)
}
sb = page_address(rdev->sb_page);
sb->data_size = cpu_to_le64(num_sectors);
- sb->super_offset = rdev->sb_start;
+ sb->super_offset = cpu_to_le64(rdev->sb_start);
sb->sb_csum = calc_sb_1_csum(sb);
md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size,
rdev->sb_page);
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index f53f4f89550..b4de9c3e5ca 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1569,11 +1569,24 @@ retry_write:
mbio->bi_private = r10_bio;
atomic_inc(&r10_bio->remaining);
+
+ cb = blk_check_plugged(raid10_unplug, mddev,
+ sizeof(*plug));
+ if (cb)
+ plug = container_of(cb, struct raid10_plug_cb,
+ cb);
+ else
+ plug = NULL;
spin_lock_irqsave(&conf->device_lock, flags);
- bio_list_add(&conf->pending_bio_list, mbio);
- conf->pending_count++;
+ if (plug) {
+ bio_list_add(&plug->pending, mbio);
+ plug->pending_cnt++;
+ } else {
+ bio_list_add(&conf->pending_bio_list, mbio);
+ conf->pending_count++;
+ }
spin_unlock_irqrestore(&conf->device_lock, flags);
- if (!mddev_check_plugged(mddev))
+ if (!plug)
md_wakeup_thread(mddev->thread);
}
}
diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c
index 93609091cb2..9dad717fb78 100644
--- a/drivers/media/platform/davinci/vpfe_capture.c
+++ b/drivers/media/platform/davinci/vpfe_capture.c
@@ -1706,27 +1706,9 @@ static long vpfe_param_handler(struct file *file, void *priv,
switch (cmd) {
case VPFE_CMD_S_CCDC_RAW_PARAMS:
+ ret = -EINVAL;
v4l2_warn(&vpfe_dev->v4l2_dev,
- "VPFE_CMD_S_CCDC_RAW_PARAMS: experimental ioctl\n");
- if (ccdc_dev->hw_ops.set_params) {
- ret = ccdc_dev->hw_ops.set_params(param);
- if (ret) {
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
- "Error setting parameters in CCDC\n");
- goto unlock_out;
- }
- ret = vpfe_get_ccdc_image_format(vpfe_dev,
- &vpfe_dev->fmt);
- if (ret < 0) {
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
- "Invalid image format at CCDC\n");
- goto unlock_out;
- }
- } else {
- ret = -EINVAL;
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
- "VPFE_CMD_S_CCDC_RAW_PARAMS not supported\n");
- }
+ "VPFE_CMD_S_CCDC_RAW_PARAMS not supported\n");
break;
default:
ret = -ENOTTY;
diff --git a/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.c b/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.c
index bb279e79f76..cf531fc2faf 100644
--- a/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.c
+++ b/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.c
@@ -369,6 +369,7 @@ static int msm_fd_open(struct file *file)
ctx->vb2_q.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
ctx->vb2_q.io_modes = VB2_USERPTR;
ctx->vb2_q.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+ mutex_init(&ctx->lock);
ret = vb2_queue_init(&ctx->vb2_q);
if (ret < 0) {
dev_err(device->dev, "Error queue init\n");
@@ -402,7 +403,9 @@ static int msm_fd_release(struct file *file)
{
struct fd_ctx *ctx = msm_fd_ctx_from_fh(file->private_data);
+ mutex_lock(&ctx->lock);
vb2_queue_release(&ctx->vb2_q);
+ mutex_unlock(&ctx->lock);
vfree(ctx->stats);
@@ -428,7 +431,9 @@ static unsigned int msm_fd_poll(struct file *file,
struct fd_ctx *ctx = msm_fd_ctx_from_fh(file->private_data);
unsigned int ret;
+ mutex_lock(&ctx->lock);
ret = vb2_poll(&ctx->vb2_q, file, wait);
+ mutex_unlock(&ctx->lock);
if (atomic_read(&ctx->subscribed_for_event)) {
poll_wait(file, &ctx->fh.wait, wait);
@@ -666,9 +671,9 @@ static int msm_fd_reqbufs(struct file *file,
int ret;
struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh);
- mutex_lock(&ctx->fd_device->recovery_lock);
+ mutex_lock(&ctx->lock);
ret = vb2_reqbufs(&ctx->vb2_q, req);
- mutex_unlock(&ctx->fd_device->recovery_lock);
+ mutex_unlock(&ctx->lock);
return ret;
}
@@ -684,9 +689,9 @@ static int msm_fd_qbuf(struct file *file, void *fh,
int ret;
struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh);
- mutex_lock(&ctx->fd_device->recovery_lock);
+ mutex_lock(&ctx->lock);
ret = vb2_qbuf(&ctx->vb2_q, pb);
- mutex_unlock(&ctx->fd_device->recovery_lock);
+ mutex_unlock(&ctx->lock);
return ret;
}
@@ -703,9 +708,9 @@ static int msm_fd_dqbuf(struct file *file,
int ret;
struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh);
- mutex_lock(&ctx->fd_device->recovery_lock);
+ mutex_lock(&ctx->lock);
ret = vb2_dqbuf(&ctx->vb2_q, pb, file->f_flags & O_NONBLOCK);
- mutex_unlock(&ctx->fd_device->recovery_lock);
+ mutex_unlock(&ctx->lock);
return ret;
}
@@ -721,7 +726,9 @@ static int msm_fd_streamon(struct file *file,
struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh);
int ret;
+ mutex_lock(&ctx->lock);
ret = vb2_streamon(&ctx->vb2_q, buf_type);
+ mutex_unlock(&ctx->lock);
if (ret < 0)
dev_err(ctx->fd_device->dev, "Stream on fails\n");
@@ -740,7 +747,9 @@ static int msm_fd_streamoff(struct file *file,
struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh);
int ret;
+ mutex_lock(&ctx->lock);
ret = vb2_streamoff(&ctx->vb2_q, buf_type);
+ mutex_unlock(&ctx->lock);
if (ret < 0)
dev_err(ctx->fd_device->dev, "Stream off fails\n");
diff --git a/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.h b/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.h
index 84ffa8c2414..930cc3f4893 100644
--- a/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.h
+++ b/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.h
@@ -153,6 +153,8 @@ struct fd_ctx {
struct msm_fd_mem_pool mem_pool;
struct msm_fd_stats *stats;
struct msm_fd_buf_handle work_buf;
+ struct completion *wait_stop_stream;
+ struct mutex lock;
};
/*
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
index 577251ca7a3..c83ad8ef1c1 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
@@ -90,8 +90,8 @@ struct msm_isp_bufq *msm_isp_get_bufq(
uint32_t bufq_index = bufq_handle & 0xFF;
if ((bufq_handle == 0) ||
- (bufq_index > buf_mgr->num_buf_q) ||
- (bufq_index >= BUF_MGR_NUM_BUF_Q) )
+ (bufq_index >= buf_mgr->num_buf_q) ||
+ (bufq_index >= BUF_MGR_NUM_BUF_Q))
return NULL;
bufq = &buf_mgr->bufq[bufq_index];
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
index d5ccf415574..bd89f3f2eaf 100644..100755
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
@@ -823,12 +823,18 @@ int msm_isp_update_stats_stream(struct vfe_device *vfe_dev, void *arg)
struct msm_vfe_axi_stream_cfg_update_info *update_info = NULL;
struct msm_isp_sw_framskip *sw_skip_info = NULL;
+ if (update_cmd->num_streams > MSM_ISP_STATS_MAX) {
+ pr_err("%s: Invalid num_streams %d\n",
+ __func__, update_cmd->num_streams);
+ return -EINVAL;
+ }
+
/*validate request*/
for (i = 0; i < update_cmd->num_streams; i++) {
update_info = &update_cmd->update_info[i];
/*check array reference bounds*/
if (STATS_IDX(update_info->stream_handle)
- > vfe_dev->hw_info->stats_hw_info->num_stats_type) {
+ >= vfe_dev->hw_info->stats_hw_info->num_stats_type) {
pr_err("%s: stats idx %d out of bound!", __func__,
STATS_IDX(update_info->stream_handle));
return -EINVAL;
diff --git a/drivers/media/platform/msm/camera_v2/msm.c b/drivers/media/platform/msm/camera_v2/msm.c
index dd228992fa4..4a886eb22ef 100644
--- a/drivers/media/platform/msm/camera_v2/msm.c
+++ b/drivers/media/platform/msm/camera_v2/msm.c
@@ -31,7 +31,6 @@
#include "msm_sd.h"
#include <media/msmb_generic_buf_mgr.h>
-
static struct v4l2_device *msm_v4l2_dev;
static struct list_head ordered_sd_list;
@@ -140,7 +139,7 @@ typedef int (*msm_queue_find_func)(void *d1, void *d2);
#define msm_queue_find(queue, type, member, func, data) ({\
unsigned long flags; \
struct msm_queue_head *__q = (queue); \
- type *node = 0; \
+ type *node = NULL; \
typeof(node) __ret = NULL; \
msm_queue_find_func __f = (func); \
spin_lock_irqsave(&__q->lock, flags); \
@@ -256,22 +255,46 @@ void msm_delete_stream(unsigned int session_id, unsigned int stream_id)
struct msm_session *session = NULL;
struct msm_stream *stream = NULL;
unsigned long flags;
+ int try_count = 0;
session = msm_queue_find(msm_session_q, struct msm_session,
list, __msm_queue_find_session, &session_id);
+
if (!session)
return;
- stream = msm_queue_find(&session->stream_q, struct msm_stream,
- list, __msm_queue_find_stream, &stream_id);
- if (!stream)
- return;
- spin_lock_irqsave(&(session->stream_q.lock), flags);
- list_del_init(&stream->list);
- session->stream_q.len--;
- kfree(stream);
- stream = NULL;
- spin_unlock_irqrestore(&(session->stream_q.lock), flags);
+ while (1) {
+
+ if (try_count > 5) {
+ pr_err("%s : not able to delete stream %d\n",
+ __func__, __LINE__);
+ break;
+ }
+
+ write_lock(&session->stream_rwlock);
+ try_count++;
+ stream = msm_queue_find(&session->stream_q, struct msm_stream,
+ list, __msm_queue_find_stream, &stream_id);
+
+ if (!stream) {
+ write_unlock(&session->stream_rwlock);
+ return;
+ }
+
+ if (msm_vb2_get_stream_state(stream) != 1) {
+ write_unlock(&session->stream_rwlock);
+ continue;
+ }
+
+ spin_lock_irqsave(&(session->stream_q.lock), flags);
+ list_del_init(&stream->list);
+ session->stream_q.len--;
+ kfree(stream);
+ stream = NULL;
+ spin_unlock_irqrestore(&(session->stream_q.lock), flags);
+ write_unlock(&session->stream_rwlock);
+ break;
+ }
}
@@ -338,6 +361,11 @@ static void msm_add_sd_in_position(struct msm_sd_subdev *msm_subdev,
struct msm_sd_subdev *temp_sd;
list_for_each_entry(temp_sd, sd_list, list) {
+ if (temp_sd == msm_subdev) {
+ pr_err("%s :Fail to add the same sd %d\n",
+ __func__, __LINE__);
+ return;
+ }
if (msm_subdev->close_seq < temp_sd->close_seq) {
list_add_tail(&msm_subdev->list, &temp_sd->list);
return;
@@ -399,6 +427,7 @@ int msm_create_session(unsigned int session_id, struct video_device *vdev)
msm_enqueue(msm_session_q, &session->list);
mutex_init(&session->lock);
mutex_init(&session->close_lock);
+ rwlock_init(&session->stream_rwlock);
return 0;
}
@@ -929,17 +958,25 @@ static struct v4l2_file_operations msm_fops = {
#endif
};
-struct msm_stream *msm_get_stream(unsigned int session_id,
- unsigned int stream_id)
+struct msm_session *msm_get_session(unsigned int session_id)
{
struct msm_session *session;
- struct msm_stream *stream;
session = msm_queue_find(msm_session_q, struct msm_session,
list, __msm_queue_find_session, &session_id);
if (!session)
return ERR_PTR(-EINVAL);
+ return session;
+}
+EXPORT_SYMBOL(msm_get_session);
+
+
+struct msm_stream *msm_get_stream(struct msm_session *session,
+ unsigned int stream_id)
+{
+ struct msm_stream *stream;
+
stream = msm_queue_find(&session->stream_q, struct msm_stream,
list, __msm_queue_find_stream, &stream_id);
@@ -993,6 +1030,33 @@ struct msm_stream *msm_get_stream_from_vb2q(struct vb2_queue *q)
return NULL;
}
+struct msm_session *msm_get_session_from_vb2q(struct vb2_queue *q)
+{
+ struct msm_session *session;
+ struct msm_stream *stream;
+ unsigned long flags1;
+ unsigned long flags2;
+
+ spin_lock_irqsave(&msm_session_q->lock, flags1);
+ list_for_each_entry(session, &(msm_session_q->list), list) {
+ spin_lock_irqsave(&(session->stream_q.lock), flags2);
+ list_for_each_entry(
+ stream, &(session->stream_q.list), list) {
+ if (stream->vb2_q == q) {
+ spin_unlock_irqrestore
+ (&(session->stream_q.lock), flags2);
+ spin_unlock_irqrestore
+ (&msm_session_q->lock, flags1);
+ return session;
+ }
+ }
+ spin_unlock_irqrestore(&(session->stream_q.lock), flags2);
+ }
+ spin_unlock_irqrestore(&msm_session_q->lock, flags1);
+ return NULL;
+}
+EXPORT_SYMBOL(msm_get_session_from_vb2q);
+
static struct v4l2_subdev *msm_sd_find(const char *name)
{
unsigned long flags;
diff --git a/drivers/media/platform/msm/camera_v2/msm.h b/drivers/media/platform/msm/camera_v2/msm.h
index 6eba37b95df..095a6db0526 100644
--- a/drivers/media/platform/msm/camera_v2/msm.h
+++ b/drivers/media/platform/msm/camera_v2/msm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015, 2017 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -108,6 +108,7 @@ struct msm_session {
struct msm_queue_head stream_q;
struct mutex lock;
struct mutex close_lock;
+ rwlock_t stream_rwlock;
};
void msm_pm_qos_update_request(int val);
@@ -121,10 +122,12 @@ int msm_create_stream(unsigned int session_id,
void msm_delete_stream(unsigned int session_id, unsigned int stream_id);
int msm_create_command_ack_q(unsigned int session_id, unsigned int stream_id);
void msm_delete_command_ack_q(unsigned int session_id, unsigned int stream_id);
-struct msm_stream *msm_get_stream(unsigned int session_id,
+struct msm_session *msm_get_session(unsigned int session_id);
+struct msm_stream *msm_get_stream(struct msm_session *session,
unsigned int stream_id);
struct vb2_queue *msm_get_stream_vb2q(unsigned int session_id,
unsigned int stream_id);
struct msm_stream *msm_get_stream_from_vb2q(struct vb2_queue *q);
+struct msm_session *msm_get_session_from_vb2q(struct vb2_queue *q);
struct msm_session *msm_session_find(unsigned int session_id);
#endif /*_MSM_H */
diff --git a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
index d90af616b59..18436734f4f 100644
--- a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
+++ b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
@@ -205,8 +205,8 @@ static void msm_buf_mngr_sd_shutdown(struct msm_buf_mngr_device *dev,
if (!list_empty(&dev->buf_qhead)) {
list_for_each_entry_safe(bufs,
save, &dev->buf_qhead, entry) {
- pr_info("%s: Delete invalid bufs =%lx, session_id=%u, bufs->ses_id=%d, str_id=%d, idx=%d\n",
- __func__, (unsigned long)bufs, session->session,
+ pr_info("%s: Delete invalid bufs =%pK, session_id=%u, bufs->ses_id=%d, str_id=%d, idx=%d\n",
+ __func__, (void *)bufs, session->session,
bufs->session_id, bufs->stream_id,
bufs->vb2_buf->v4l2_buf.index);
if (session->session == bufs->session_id) {
diff --git a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
index 8b756f12b31..63f21097b6e 100644
--- a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
+++ b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015, 2017 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -43,16 +43,24 @@ static int msm_vb2_queue_setup(struct vb2_queue *q,
int msm_vb2_buf_init(struct vb2_buffer *vb)
{
struct msm_stream *stream;
+ struct msm_session *session;
struct msm_vb2_buffer *msm_vb2_buf;
+ session = msm_get_session_from_vb2q(vb->vb2_queue);
+ if (IS_ERR_OR_NULL(session))
+ return -EINVAL;
+
+ read_lock(&session->stream_rwlock);
+
stream = msm_get_stream_from_vb2q(vb->vb2_queue);
if (!stream) {
pr_err("%s: Couldn't find stream\n", __func__);
+ read_unlock(&session->stream_rwlock);
return -EINVAL;
}
msm_vb2_buf = container_of(vb, struct msm_vb2_buffer, vb2_buf);
msm_vb2_buf->in_freeq = 0;
-
+ read_unlock(&session->stream_rwlock);
return 0;
}
@@ -60,6 +68,7 @@ static void msm_vb2_buf_queue(struct vb2_buffer *vb)
{
struct msm_vb2_buffer *msm_vb2;
struct msm_stream *stream;
+ struct msm_session *session;
unsigned long flags;
msm_vb2 = container_of(vb, struct msm_vb2_buffer, vb2_buf);
@@ -69,21 +78,30 @@ static void msm_vb2_buf_queue(struct vb2_buffer *vb)
return;
}
+ session = msm_get_session_from_vb2q(vb->vb2_queue);
+ if (IS_ERR_OR_NULL(session))
+ return;
+
+ read_lock(&session->stream_rwlock);
+
stream = msm_get_stream_from_vb2q(vb->vb2_queue);
if (!stream) {
pr_err("%s:%d] NULL stream", __func__, __LINE__);
+ read_unlock(&session->stream_rwlock);
return;
}
spin_lock_irqsave(&stream->stream_lock, flags);
list_add_tail(&msm_vb2->list, &stream->queued_list);
spin_unlock_irqrestore(&stream->stream_lock, flags);
+ read_unlock(&session->stream_rwlock);
}
static int msm_vb2_buf_finish(struct vb2_buffer *vb)
{
struct msm_vb2_buffer *msm_vb2;
struct msm_stream *stream;
+ struct msm_session *session;
unsigned long flags;
struct msm_vb2_buffer *msm_vb2_entry, *temp;
@@ -94,9 +112,16 @@ static int msm_vb2_buf_finish(struct vb2_buffer *vb)
return -EINVAL;
}
+ session = msm_get_session_from_vb2q(vb->vb2_queue);
+ if (IS_ERR_OR_NULL(session))
+ return -EINVAL;
+
+ read_lock(&session->stream_rwlock);
+
stream = msm_get_stream_from_vb2q(vb->vb2_queue);
if (!stream) {
pr_err("%s:%d] NULL stream", __func__, __LINE__);
+ read_unlock(&session->stream_rwlock);
return -EINVAL;
}
@@ -109,6 +134,7 @@ static int msm_vb2_buf_finish(struct vb2_buffer *vb)
}
}
spin_unlock_irqrestore(&stream->stream_lock, flags);
+ read_unlock(&session->stream_rwlock);
return 0;
}
@@ -116,6 +142,7 @@ static void msm_vb2_buf_cleanup(struct vb2_buffer *vb)
{
struct msm_vb2_buffer *msm_vb2;
struct msm_stream *stream;
+ struct msm_session *session;
unsigned long flags;
msm_vb2 = container_of(vb, struct msm_vb2_buffer, vb2_buf);
@@ -125,17 +152,43 @@ static void msm_vb2_buf_cleanup(struct vb2_buffer *vb)
return;
}
+ session = msm_get_session_from_vb2q(vb->vb2_queue);
+ if (IS_ERR_OR_NULL(session))
+ return;
+
+ read_lock(&session->stream_rwlock);
+
stream = msm_get_stream_from_vb2q(vb->vb2_queue);
if (!stream) {
- pr_err_ratelimited("%s:%d] NULL stream", __func__, __LINE__);
+ pr_err("%s:%d] NULL stream", __func__, __LINE__);
+ read_unlock(&session->stream_rwlock);
return;
}
spin_lock_irqsave(&stream->stream_lock, flags);
INIT_LIST_HEAD(&stream->queued_list);
spin_unlock_irqrestore(&stream->stream_lock, flags);
+ read_unlock(&session->stream_rwlock);
}
+int msm_vb2_get_stream_state(struct msm_stream *stream)
+{
+ struct msm_vb2_buffer *msm_vb2, *temp;
+ unsigned long flags;
+ int rc = 1;
+
+ spin_lock_irqsave(&stream->stream_lock, flags);
+ list_for_each_entry_safe(msm_vb2, temp, &(stream->queued_list), list) {
+ if (msm_vb2->in_freeq != 0) {
+ rc = 0;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&stream->stream_lock, flags);
+ return rc;
+}
+EXPORT_SYMBOL(msm_vb2_get_stream_state);
+
static struct vb2_ops msm_vb2_get_q_op = {
.queue_setup = msm_vb2_queue_setup,
.buf_init = msm_vb2_buf_init,
@@ -188,14 +241,23 @@ static struct vb2_buffer *msm_vb2_get_buf(int session_id,
unsigned int stream_id)
{
struct msm_stream *stream;
+ struct msm_session *session;
struct vb2_buffer *vb2_buf = NULL;
struct msm_vb2_buffer *msm_vb2 = NULL;
unsigned long flags;
- stream = msm_get_stream(session_id, stream_id);
- if (IS_ERR_OR_NULL(stream))
+ session = msm_get_session(session_id);
+ if (IS_ERR_OR_NULL(session))
return NULL;
+ read_lock(&session->stream_rwlock);
+
+ stream = msm_get_stream(session, stream_id);
+ if (IS_ERR_OR_NULL(stream)) {
+ read_unlock(&session->stream_rwlock);
+ return NULL;
+ }
+
spin_lock_irqsave(&stream->stream_lock, flags);
if (!stream->vb2_q) {
@@ -218,6 +280,7 @@ static struct vb2_buffer *msm_vb2_get_buf(int session_id,
vb2_buf = NULL;
end:
spin_unlock_irqrestore(&stream->stream_lock, flags);
+ read_unlock(&session->stream_rwlock);
return vb2_buf;
}
@@ -225,13 +288,23 @@ static int msm_vb2_put_buf(struct vb2_buffer *vb, int session_id,
unsigned int stream_id)
{
struct msm_stream *stream;
+ struct msm_session *session;
struct msm_vb2_buffer *msm_vb2;
struct vb2_buffer *vb2_buf = NULL;
int rc = 0;
unsigned long flags;
- stream = msm_get_stream(session_id, stream_id);
- if (IS_ERR_OR_NULL(stream))
+
+ session = msm_get_session(session_id);
+ if (IS_ERR_OR_NULL(session))
+ return -EINVAL;
+
+ read_lock(&session->stream_rwlock);
+
+ stream = msm_get_stream(session, stream_id);
+ if (IS_ERR_OR_NULL(stream)) {
+ read_unlock(&session->stream_rwlock);
return -EINVAL;
+ }
spin_lock_irqsave(&stream->stream_lock, flags);
if (vb) {
@@ -244,6 +317,7 @@ static int msm_vb2_put_buf(struct vb2_buffer *vb, int session_id,
pr_err("VB buffer is INVALID vb=%pK, ses_id=%d, str_id=%d\n",
vb, session_id, stream_id);
spin_unlock_irqrestore(&stream->stream_lock, flags);
+ read_unlock(&session->stream_rwlock);
return -EINVAL;
}
msm_vb2 =
@@ -259,6 +333,7 @@ static int msm_vb2_put_buf(struct vb2_buffer *vb, int session_id,
rc = -EINVAL;
}
spin_unlock_irqrestore(&stream->stream_lock, flags);
+ read_unlock(&session->stream_rwlock);
return rc;
}
@@ -268,12 +343,22 @@ static int msm_vb2_buf_done(struct vb2_buffer *vb, int session_id,
unsigned long flags;
struct msm_vb2_buffer *msm_vb2;
struct msm_stream *stream;
+ struct msm_session *session;
struct vb2_buffer *vb2_buf = NULL;
int rc = 0;
- stream = msm_get_stream(session_id, stream_id);
- if (IS_ERR_OR_NULL(stream))
+ session = msm_get_session(session_id);
+ if (IS_ERR_OR_NULL(session))
+ return 0;
+
+ read_lock(&session->stream_rwlock);
+
+ stream = msm_get_stream(session, stream_id);
+ if (IS_ERR_OR_NULL(stream)) {
+ read_unlock(&session->stream_rwlock);
return -EINVAL;
+ }
+
spin_lock_irqsave(&stream->stream_lock, flags);
if (vb) {
list_for_each_entry(msm_vb2, &(stream->queued_list), list) {
@@ -285,6 +370,7 @@ static int msm_vb2_buf_done(struct vb2_buffer *vb, int session_id,
pr_err("VB buffer is INVALID ses_id=%d, str_id=%d, vb=%pK\n",
session_id, stream_id, vb);
spin_unlock_irqrestore(&stream->stream_lock, flags);
+ read_unlock(&session->stream_rwlock);
return -EINVAL;
}
msm_vb2 =
@@ -302,6 +388,7 @@ static int msm_vb2_buf_done(struct vb2_buffer *vb, int session_id,
rc = -EINVAL;
}
spin_unlock_irqrestore(&stream->stream_lock, flags);
+ read_unlock(&session->stream_rwlock);
return rc;
}
@@ -309,12 +396,22 @@ static int msm_vb2_flush_buf(int session_id, unsigned int stream_id)
{
unsigned long flags;
struct msm_vb2_buffer *msm_vb2;
+ struct msm_session *session;
struct msm_stream *stream;
struct vb2_buffer *vb2_buf = NULL;
- stream = msm_get_stream(session_id, stream_id);
- if (IS_ERR_OR_NULL(stream))
+ session = msm_get_session(session_id);
+ if (IS_ERR_OR_NULL(session))
return -EINVAL;
+
+ read_lock(&session->stream_rwlock);
+
+ stream = msm_get_stream(session, stream_id);
+ if (IS_ERR_OR_NULL(stream)) {
+ read_unlock(&session->stream_rwlock);
+ return -EINVAL;
+ }
+
spin_lock_irqsave(&stream->stream_lock, flags);
list_for_each_entry(msm_vb2, &(stream->queued_list), list) {
vb2_buf = &(msm_vb2->vb2_buf);
@@ -323,6 +420,7 @@ static int msm_vb2_flush_buf(int session_id, unsigned int stream_id)
msm_vb2->in_freeq = 0;
}
spin_unlock_irqrestore(&stream->stream_lock, flags);
+ read_unlock(&session->stream_rwlock);
return 0;
}
@@ -342,4 +440,3 @@ int msm_vb2_request_cb(struct msm_sd_req_vb2_q *req)
return 0;
}
-
diff --git a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.h b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.h
index 7082f8583d1..b04d31b1e44 100644
--- a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.h
+++ b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, 2017 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -66,5 +66,6 @@ struct msm_stream {
struct vb2_ops *msm_vb2_get_q_ops(void);
struct vb2_mem_ops *msm_vb2_get_q_mem_ops(void);
int msm_vb2_request_cb(struct msm_sd_req_vb2_q *req_sd);
+int msm_vb2_get_stream_state(struct msm_stream *stream);
#endif /*_MSM_VB_H */
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c
index 5af2eafb122..742401b7814 100644..100755
--- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014,2016-2017 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -17,7 +17,8 @@
#undef CDBG
#define CDBG(fmt, args...) pr_debug(fmt, ##args)
#define S_I2C_DBG(fmt, args...) pr_debug(fmt, ##args)
-
+#define MAX_I2C_ADDR_TYPE_SIZE (MSM_CAMERA_I2C_3B_ADDR + 1)
+#define MAX_I2C_DATA_TYPE_SIZE (MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA + 1)
#define I2C_COMPARE_MATCH 0
#define I2C_COMPARE_MISMATCH 1
#define I2C_POLL_MAX_ITERATION 20
@@ -27,7 +28,7 @@ int32_t msm_camera_cci_i2c_read(struct msm_camera_i2c_client *client,
enum msm_camera_i2c_data_type data_type)
{
int32_t rc = -EFAULT;
- unsigned char buf[client->addr_type+data_type];
+ unsigned char buf[MAX_I2C_ADDR_TYPE_SIZE + MAX_I2C_DATA_TYPE_SIZE];
struct msm_camera_cci_ctrl cci_ctrl;
if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c
index f96cae163de..bf0ebfd9936 100755
--- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2015,2017 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -103,7 +103,11 @@ static int32_t msm_sensor_driver_create_i2c_v4l_subdev
s_ctrl->msm_sd.sd.entity.name = s_ctrl->msm_sd.sd.name;
s_ctrl->sensordata->sensor_info->session_id = session_id;
s_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x3;
- msm_sd_register(&s_ctrl->msm_sd);
+ rc = msm_sd_register(&s_ctrl->msm_sd);
+ if (rc < 0) {
+ pr_err("failed: msm_sd_register rc %d", rc);
+ return rc;
+ }
CDBG("%s:%d\n", __func__, __LINE__);
return rc;
}
@@ -133,7 +137,11 @@ static int32_t msm_sensor_driver_create_v4l_subdev
s_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_SENSOR;
s_ctrl->msm_sd.sd.entity.name = s_ctrl->msm_sd.sd.name;
s_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x3;
- msm_sd_register(&s_ctrl->msm_sd);
+ rc = msm_sd_register(&s_ctrl->msm_sd);
+ if (rc < 0) {
+ pr_err("failed: msm_sd_register rc %d", rc);
+ return rc;
+ }
msm_sensor_v4l2_subdev_fops = v4l2_subdev_fops;
#ifdef CONFIG_COMPAT
msm_sensor_v4l2_subdev_fops.compat_ioctl32 =
@@ -927,12 +935,6 @@ CSID_TG:
pr_err("%s probe succeeded", slave_info->sensor_name);
/*
- Set probe succeeded flag to 1 so that no other camera shall
- * probed on this slot
- */
- s_ctrl->is_probe_succeed = 1;
-
- /*
* Update the subdevice id of flash-src based on availability in kernel.
*/
if (strlen(slave_info->flash_name) == 0) {
@@ -984,6 +986,11 @@ CSID_TG:
msm_sensor_fill_sensor_info(s_ctrl, probed_info, entity_name);
+ /*
+ * Set probe succeeded flag to 1 so that no other camera shall
+ * probed on this slot
+ */
+ s_ctrl->is_probe_succeed = 1;
return rc;
camera_power_down:
diff --git a/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c b/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c
index 1ec825524a2..5b18bc36742 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c
@@ -427,11 +427,13 @@ static long msm_ois_subdev_ioctl(struct v4l2_subdev *sd,
pr_err("o_ctrl->i2c_client.i2c_func_tbl NULL\n");
return -EINVAL;
} else {
+ mutex_lock(o_ctrl->ois_mutex);
rc = msm_ois_power_down(o_ctrl);
if (rc < 0) {
pr_err("%s:%d OIS Power down failed\n",
__func__, __LINE__);
}
+ mutex_unlock(o_ctrl->ois_mutex);
return msm_ois_close(sd, NULL);
}
default:
@@ -596,6 +598,10 @@ static long msm_ois_subdev_do_ioctl(
parg = &ois_data;
break;
}
+ break;
+ case VIDIOC_MSM_OIS_CFG:
+ pr_err("%s: invalid cmd 0x%x received\n", __func__, cmd);
+ return -EINVAL;
}
rc = msm_ois_subdev_ioctl(sd, cmd, parg);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.c b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
index 8168dc6b999..43a42661d79 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_debug.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
@@ -17,7 +17,7 @@
#include "vidc_hfi_api.h"
#define MAX_DBG_BUF_SIZE 4096
-int msm_vidc_debug = 0;
+int msm_vidc_debug = VIDC_ERR | VIDC_WARN;
int msm_vidc_debug_out = VIDC_OUT_PRINTK;
int msm_fw_debug = 0x18;
int msm_fw_debug_mode = 0x1;
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
index 72e3fa65248..257bb7a6ff5 100644
--- a/drivers/media/rc/imon.c
+++ b/drivers/media/rc/imon.c
@@ -1530,7 +1530,7 @@ static void imon_incoming_packet(struct imon_context *ictx,
if (kc == KEY_KEYBOARD && !ictx->release_code) {
ictx->last_keycode = kc;
if (!nomouse) {
- ictx->pad_mouse = ~(ictx->pad_mouse) & 0x1;
+ ictx->pad_mouse = !ictx->pad_mouse;
dev_dbg(dev, "toggling to %s mode\n",
ictx->pad_mouse ? "mouse" : "keyboard");
spin_unlock_irqrestore(&ictx->kc_lock, flags);
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-eeprom.c b/drivers/media/usb/pvrusb2/pvrusb2-eeprom.c
index 9515f3a68f8..122815e1cb6 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-eeprom.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-eeprom.c
@@ -123,15 +123,10 @@ int pvr2_eeprom_analyze(struct pvr2_hdw *hdw)
memset(&tvdata,0,sizeof(tvdata));
eeprom = pvr2_eeprom_fetch(hdw);
- if (!eeprom) return -EINVAL;
-
- {
- struct i2c_client fake_client;
- /* Newer version expects a useless client interface */
- fake_client.addr = hdw->eeprom_addr;
- fake_client.adapter = &hdw->i2c_adap;
- tveeprom_hauppauge_analog(&fake_client,&tvdata,eeprom);
- }
+ if (!eeprom)
+ return -EINVAL;
+
+ tveeprom_hauppauge_analog(NULL, &tvdata, eeprom);
trace_eeprom("eeprom assumed v4l tveeprom module");
trace_eeprom("eeprom direct call results:");
diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index a6487754b37..8e6b851e755 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -264,7 +264,7 @@ static int put_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_
struct v4l2_standard32 {
__u32 index;
- compat_u64 id;
+ __u32 id[2]; /* __u64 would get the alignment wrong */
__u8 name[24];
struct v4l2_fract frameperiod; /* Frames, not fields */
__u32 framelines;
@@ -284,7 +284,7 @@ static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32
{
if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_standard32)) ||
put_user(kp->index, &up->index) ||
- put_user(kp->id, &up->id) ||
+ copy_to_user(up->id, &kp->id, sizeof(__u64)) ||
copy_to_user(up->name, kp->name, 24) ||
copy_to_user(&up->frameperiod, &kp->frameperiod, sizeof(kp->frameperiod)) ||
put_user(kp->framelines, &up->framelines) ||
@@ -593,10 +593,10 @@ struct v4l2_input32 {
__u32 type; /* Type of input */
__u32 audioset; /* Associated audios (bitfield) */
__u32 tuner; /* Associated tuner */
- compat_u64 std;
+ v4l2_std_id std;
__u32 status;
__u32 reserved[4];
-};
+} __attribute__ ((packed));
/* The 64-bit v4l2_input struct has extra padding at the end of the struct.
Otherwise it is identical to the 32-bit version. */
@@ -740,7 +740,6 @@ struct v4l2_event32 {
struct v4l2_event_ctrl ctrl;
struct v4l2_event_frame_sync frame_sync;
__u8 data[64];
- compat_s64 value64;
} u;
__u32 pending;
__u32 sequence;
diff --git a/drivers/mfd/omap-usb-tll.c b/drivers/mfd/omap-usb-tll.c
index c7576a503e5..2afadd00d3f 100644
--- a/drivers/mfd/omap-usb-tll.c
+++ b/drivers/mfd/omap-usb-tll.c
@@ -380,8 +380,8 @@ int omap_tll_init(struct usbhs_omap_platform_data *pdata)
* and use SDR Mode
*/
reg &= ~(OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE
- | OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF
| OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE);
+ reg |= OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF;
} else if (pdata->port_mode[i] ==
OMAP_EHCI_PORT_MODE_HSIC) {
/*
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 7d394ca8545..7a997360f3f 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -69,10 +69,9 @@ obj-$(CONFIG_QCOM_LIQUID_DOCK) += qcom_liquid_dock.o
obj-y += qcom/
obj-$(CONFIG_USB_EXT_TYPE_C_PERICOM) += type-c-pericom.o
obj-$(CONFIG_USB_EXT_TYPE_C_TI) += type-c-ti.o
-obj-$(CONFIG_UID_CPUTIME) += uid_cputime.o
+obj-$(CONFIG_UID_SYS_STATS) += uid_sys_stats.o
obj-$(CONFIG_ALSA_TO_H2W) += alsa-to-h2w-headset.o
obj-$(CONFIG_MOT_UTAG) += utag/
obj-$(CONFIG_SENSORS_STML0XX) += stml0xx/
obj-$(CONFIG_DROPBOX) += dropbox.o
obj-$(CONFIG_SEC_DRIVER) += sec/
-obj-$(CONFIG_UID_SYS_STATS) += uid_sys_stats.o \ No newline at end of file
diff --git a/drivers/misc/c2port/c2port-duramar2150.c b/drivers/misc/c2port/c2port-duramar2150.c
index 5484301d57d..3dc61ea7dc6 100644
--- a/drivers/misc/c2port/c2port-duramar2150.c
+++ b/drivers/misc/c2port/c2port-duramar2150.c
@@ -129,8 +129,8 @@ static int __init duramar2150_c2port_init(void)
duramar2150_c2port_dev = c2port_device_register("uc",
&duramar2150_c2port_ops, NULL);
- if (!duramar2150_c2port_dev) {
- ret = -ENODEV;
+ if (IS_ERR(duramar2150_c2port_dev)) {
+ ret = PTR_ERR(duramar2150_c2port_dev);
goto free_region;
}
diff --git a/drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c b/drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c
index e7c28a663b6..5543059ab64 100644
--- a/drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c
+++ b/drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c
@@ -17,7 +17,6 @@
#include "q6audio_common.h"
#include "audio_utils_aio.h"
#include <sound/msm-audio-effects-q6-v2.h>
-#include <sound/msm-dts-eagle.h>
#define MAX_CHANNELS_SUPPORTED 8
#define WAIT_TIMEDOUT_DURATION_SECS 1
@@ -53,31 +52,11 @@ static void audio_effects_init_pp(struct audio_client *ac)
pr_err("%s: audio client null to init pp\n", __func__);
return;
}
- switch (ac->topology) {
- case ASM_STREAM_POSTPROC_TOPO_ID_HPX_MASTER:
-
- ret = q6asm_set_softvolume_v2(ac, &softvol,
- SOFT_VOLUME_INSTANCE_1);
- if (ret < 0)
- pr_err("%s: Send SoftVolume1 Param failed ret=%d\n",
- __func__, ret);
- ret = q6asm_set_softvolume_v2(ac, &softvol,
- SOFT_VOLUME_INSTANCE_2);
- if (ret < 0)
- pr_err("%s: Send SoftVolume2 Param failed ret=%d\n",
- __func__, ret);
-
- msm_dts_eagle_init_master_module(ac);
-
- break;
- default:
- ret = q6asm_set_softvolume_v2(ac, &softvol,
- SOFT_VOLUME_INSTANCE_1);
- if (ret < 0)
- pr_err("%s: Send SoftVolume Param failed ret=%d\n",
- __func__, ret);
- break;
- }
+ ret = q6asm_set_softvolume_v2(ac, &softvol,
+ SOFT_VOLUME_INSTANCE_1);
+ if (ret < 0)
+ pr_err("%s: Send SoftVolume Param failed ret=%d\n",
+ __func__, ret);
}
static void audio_effects_deinit_pp(struct audio_client *ac)
@@ -86,13 +65,6 @@ static void audio_effects_deinit_pp(struct audio_client *ac)
pr_err("%s: audio client null to deinit pp\n", __func__);
return;
}
- switch (ac->topology) {
- case ASM_STREAM_POSTPROC_TOPO_ID_HPX_MASTER:
- msm_dts_eagle_deinit_master_module(ac);
- break;
- default:
- break;
- }
}
static void audio_effects_event_handler(uint32_t opcode, uint32_t token,
@@ -428,33 +400,6 @@ static long audio_effects_set_pp_param(struct q6audio_effects *effects,
&(effects->audio_effects.topo_switch_vol),
(long *)&values[1], SOFT_VOLUME_INSTANCE_2);
break;
- case DTS_EAGLE_MODULE_ENABLE:
- pr_debug("%s: DTS_EAGLE_MODULE_ENABLE\n", __func__);
- if (msm_audio_effects_is_effmodule_supp_in_top(
- effects_module, effects->ac->topology)) {
- /*
- * HPX->OFF: first disable HPX and then
- * enable SA+
- * HPX->ON: first disable SA+ and then
- * enable HPX
- */
- bool hpx_state = (bool)values[1];
- if (hpx_state)
- msm_audio_effects_enable_extn(effects->ac,
- &(effects->audio_effects),
- false);
- msm_dts_eagle_enable_asm(effects->ac,
- hpx_state,
- AUDPROC_MODULE_ID_DTS_HPX_PREMIX);
- msm_dts_eagle_enable_asm(effects->ac,
- hpx_state,
- AUDPROC_MODULE_ID_DTS_HPX_POSTMIX);
- if (!hpx_state)
- msm_audio_effects_enable_extn(effects->ac,
- &(effects->audio_effects),
- true);
- }
- break;
default:
pr_err("%s: Invalid effects config module\n", __func__);
rc = -EINVAL;
diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c
index 066329df584..c8b09e4ff37 100644
--- a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c
+++ b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c
@@ -1057,6 +1057,8 @@ static int audio_aio_async_write(struct q6audio_aio *audio,
struct audio_client *ac;
struct audio_aio_write_param param;
+ memset(&param, 0, sizeof(param));
+
if (!audio || !buf_node) {
pr_err("%s NULL pointer audio=[0x%pK], buf_node=[0x%pK]\n",
__func__, audio, buf_node);
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index dc78b865a59..2da76ce8274 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -6147,11 +6147,16 @@ static int __qseecom_qteec_issue_cmd(struct qseecom_dev_handle *data,
void *cmd_buf = NULL;
size_t cmd_len;
struct sglist_info *table = data->sglistinfo_ptr;
+ void *req_ptr = NULL;
+ void *resp_ptr = NULL;
ret = __qseecom_qteec_validate_msg(data, req);
if (ret)
return ret;
+ req_ptr = req->req_ptr;
+ resp_ptr = req->resp_ptr;
+
/* find app_id & img_name from list */
spin_lock_irqsave(&qseecom.registered_app_list_lock, flags);
list_for_each_entry(ptr_app, &qseecom.registered_app_list_head,
@@ -6171,6 +6176,11 @@ static int __qseecom_qteec_issue_cmd(struct qseecom_dev_handle *data,
return -ENOENT;
}
+ req->req_ptr = (void *)__qseecom_uvirt_to_kvirt(data,
+ (uintptr_t)req->req_ptr);
+ req->resp_ptr = (void *)__qseecom_uvirt_to_kvirt(data,
+ (uintptr_t)req->resp_ptr);
+
if ((cmd_id == QSEOS_TEE_OPEN_SESSION) ||
(cmd_id == QSEOS_TEE_REQUEST_CANCELLATION)) {
ret = __qseecom_update_qteec_req_buf(
@@ -6182,10 +6192,10 @@ static int __qseecom_qteec_issue_cmd(struct qseecom_dev_handle *data,
if (qseecom.qsee_version < QSEE_VERSION_40) {
ireq.app_id = data->client.app_id;
ireq.req_ptr = (uint32_t)__qseecom_uvirt_to_kphys(data,
- (uintptr_t)req->req_ptr);
+ (uintptr_t)req_ptr);
ireq.req_len = req->req_len;
ireq.resp_ptr = (uint32_t)__qseecom_uvirt_to_kphys(data,
- (uintptr_t)req->resp_ptr);
+ (uintptr_t)resp_ptr);
ireq.resp_len = req->resp_len;
ireq.sglistinfo_ptr = (uint32_t)virt_to_phys(table);
ireq.sglistinfo_len = SGLISTINFO_TABLE_SIZE;
@@ -6196,10 +6206,10 @@ static int __qseecom_qteec_issue_cmd(struct qseecom_dev_handle *data,
} else {
ireq_64bit.app_id = data->client.app_id;
ireq_64bit.req_ptr = (uint64_t)__qseecom_uvirt_to_kphys(data,
- (uintptr_t)req->req_ptr);
+ (uintptr_t)req_ptr);
ireq_64bit.req_len = req->req_len;
ireq_64bit.resp_ptr = (uint64_t)__qseecom_uvirt_to_kphys(data,
- (uintptr_t)req->resp_ptr);
+ (uintptr_t)resp_ptr);
ireq_64bit.resp_len = req->resp_len;
if ((data->client.app_arch == ELFCLASS32) &&
((ireq_64bit.req_ptr >=
diff --git a/drivers/misc/uid_sys_stats.c b/drivers/misc/uid_sys_stats.c
index 3c031f9b0cd..e2d45b4f3bd 100644
--- a/drivers/misc/uid_sys_stats.c
+++ b/drivers/misc/uid_sys_stats.c
@@ -21,7 +21,6 @@
#include <linux/list.h>
#include <linux/proc_fs.h>
#include <linux/profile.h>
-#include <linux/rtmutex.h>
#include <linux/sched.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
@@ -30,27 +29,8 @@
#define UID_HASH_BITS 10
DECLARE_HASHTABLE(hash_table, UID_HASH_BITS);
-static DEFINE_RT_MUTEX(uid_lock);
-static struct proc_dir_entry *cpu_parent;
-static struct proc_dir_entry *io_parent;
-static struct proc_dir_entry *proc_parent;
-
-struct io_stats {
- u64 read_bytes;
- u64 write_bytes;
- u64 rchar;
- u64 wchar;
- u64 fsync;
-};
-
-#define UID_STATE_FOREGROUND 0
-#define UID_STATE_BACKGROUND 1
-#define UID_STATE_BUCKET_SIZE 2
-
-#define UID_STATE_TOTAL_CURR 2
-#define UID_STATE_TOTAL_LAST 3
-#define UID_STATE_DEAD_TASKS 4
-#define UID_STATE_SIZE 5
+static DEFINE_MUTEX(uid_lock);
+static struct proc_dir_entry *parent;
struct uid_entry {
uid_t uid;
@@ -60,8 +40,6 @@ struct uid_entry {
cputime_t active_stime;
unsigned long long active_power;
unsigned long long power;
- int state;
- struct io_stats io[UID_STATE_SIZE];
struct hlist_node hash;
};
@@ -94,7 +72,7 @@ static struct uid_entry *find_or_register_uid(uid_t uid)
return uid_entry;
}
-static int uid_cputime_show(struct seq_file *m, void *v)
+static int uid_stat_show(struct seq_file *m, void *v)
{
struct uid_entry *uid_entry;
struct task_struct *task, *temp;
@@ -104,7 +82,7 @@ static int uid_cputime_show(struct seq_file *m, void *v)
unsigned long bkt;
uid_t uid;
- rt_mutex_lock(&uid_lock);
+ mutex_lock(&uid_lock);
hash_for_each(hash_table, bkt, uid_entry, hash) {
uid_entry->active_stime = 0;
@@ -118,7 +96,7 @@ static int uid_cputime_show(struct seq_file *m, void *v)
uid_entry = find_or_register_uid(uid);
if (!uid_entry) {
read_unlock(&tasklist_lock);
- rt_mutex_unlock(&uid_lock);
+ mutex_unlock(&uid_lock);
pr_err("%s: failed to find the uid_entry for uid %d\n",
__func__, uid);
return -ENOMEM;
@@ -150,17 +128,17 @@ static int uid_cputime_show(struct seq_file *m, void *v)
total_power);
}
- rt_mutex_unlock(&uid_lock);
+ mutex_unlock(&uid_lock);
return 0;
}
-static int uid_cputime_open(struct inode *inode, struct file *file)
+static int uid_stat_open(struct inode *inode, struct file *file)
{
- return single_open(file, uid_cputime_show, PDE_DATA(inode));
+ return single_open(file, uid_stat_show, PDE_DATA(inode));
}
-static const struct file_operations uid_cputime_fops = {
- .open = uid_cputime_open,
+static const struct file_operations uid_stat_fops = {
+ .open = uid_stat_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
@@ -197,7 +175,7 @@ static ssize_t uid_remove_write(struct file *file,
kstrtol(end_uid, 10, &uid_end) != 0) {
return -EINVAL;
}
- rt_mutex_lock(&uid_lock);
+ mutex_lock(&uid_lock);
for (; uid_start <= uid_end; uid_start++) {
hash_for_each_possible_safe(hash_table, uid_entry, tmp,
@@ -209,7 +187,7 @@ static ssize_t uid_remove_write(struct file *file,
}
}
- rt_mutex_unlock(&uid_lock);
+ mutex_unlock(&uid_lock);
return count;
}
@@ -219,213 +197,6 @@ static const struct file_operations uid_remove_fops = {
.write = uid_remove_write,
};
-static u64 compute_write_bytes(struct task_struct *task)
-{
- if (task->ioac.write_bytes <= task->ioac.cancelled_write_bytes)
- return 0;
-
- return task->ioac.write_bytes - task->ioac.cancelled_write_bytes;
-}
-
-static void add_uid_io_stats(struct uid_entry *uid_entry,
- struct task_struct *task, int slot)
-{
- struct io_stats *io_slot = &uid_entry->io[slot];
-
- io_slot->read_bytes += task->ioac.read_bytes;
- io_slot->write_bytes += compute_write_bytes(task);
- io_slot->rchar += task->ioac.rchar;
- io_slot->wchar += task->ioac.wchar;
- io_slot->fsync += task->ioac.syscfs;
-}
-
-static void compute_uid_io_bucket_stats(struct io_stats *io_bucket,
- struct io_stats *io_curr,
- struct io_stats *io_last,
- struct io_stats *io_dead)
-{
- s64 delta;
-
- delta = io_curr->read_bytes + io_dead->read_bytes -
- io_last->read_bytes;
- if (delta > 0)
- io_bucket->read_bytes += delta;
-
- delta = io_curr->write_bytes + io_dead->write_bytes -
- io_last->write_bytes;
- if (delta > 0)
- io_bucket->write_bytes += delta;
-
- delta = io_curr->rchar + io_dead->rchar - io_last->rchar;
- if (delta > 0)
- io_bucket->rchar += delta;
-
- delta = io_curr->wchar + io_dead->wchar - io_last->wchar;
- if (delta > 0)
- io_bucket->wchar += delta;
-
- delta = io_curr->fsync + io_dead->fsync - io_last->fsync;
- if (delta > 0)
- io_bucket->fsync += delta;
-
- io_last->read_bytes = io_curr->read_bytes;
- io_last->write_bytes = io_curr->write_bytes;
- io_last->rchar = io_curr->rchar;
- io_last->wchar = io_curr->wchar;
- io_last->fsync = io_curr->fsync;
-
- memset(io_dead, 0, sizeof(struct io_stats));
-}
-
-static void update_io_stats_all_locked(void)
-{
- struct uid_entry *uid_entry;
- struct task_struct *task, *temp;
- struct user_namespace *user_ns = current_user_ns();
- unsigned long bkt;
- uid_t uid;
-
- hash_for_each(hash_table, bkt, uid_entry, hash)
- memset(&uid_entry->io[UID_STATE_TOTAL_CURR], 0,
- sizeof(struct io_stats));
-
- rcu_read_lock();
- do_each_thread(temp, task) {
- uid = from_kuid_munged(user_ns, task_uid(task));
- uid_entry = find_or_register_uid(uid);
- if (!uid_entry)
- continue;
- add_uid_io_stats(uid_entry, task, UID_STATE_TOTAL_CURR);
- } while_each_thread(temp, task);
- rcu_read_unlock();
-
- hash_for_each(hash_table, bkt, uid_entry, hash) {
- compute_uid_io_bucket_stats(&uid_entry->io[uid_entry->state],
- &uid_entry->io[UID_STATE_TOTAL_CURR],
- &uid_entry->io[UID_STATE_TOTAL_LAST],
- &uid_entry->io[UID_STATE_DEAD_TASKS]);
- }
-}
-
-static void update_io_stats_uid_locked(struct uid_entry *uid_entry)
-{
- struct task_struct *task, *temp;
- struct user_namespace *user_ns = current_user_ns();
-
- memset(&uid_entry->io[UID_STATE_TOTAL_CURR], 0,
- sizeof(struct io_stats));
-
- rcu_read_lock();
- do_each_thread(temp, task) {
- if (from_kuid_munged(user_ns, task_uid(task)) != uid_entry->uid)
- continue;
- add_uid_io_stats(uid_entry, task, UID_STATE_TOTAL_CURR);
- } while_each_thread(temp, task);
- rcu_read_unlock();
-
- compute_uid_io_bucket_stats(&uid_entry->io[uid_entry->state],
- &uid_entry->io[UID_STATE_TOTAL_CURR],
- &uid_entry->io[UID_STATE_TOTAL_LAST],
- &uid_entry->io[UID_STATE_DEAD_TASKS]);
-}
-
-static int uid_io_show(struct seq_file *m, void *v)
-{
- struct uid_entry *uid_entry;
- unsigned long bkt;
-
- rt_mutex_lock(&uid_lock);
-
- update_io_stats_all_locked();
-
- hash_for_each(hash_table, bkt, uid_entry, hash) {
- seq_printf(m, "%d %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
- uid_entry->uid,
- uid_entry->io[UID_STATE_FOREGROUND].rchar,
- uid_entry->io[UID_STATE_FOREGROUND].wchar,
- uid_entry->io[UID_STATE_FOREGROUND].read_bytes,
- uid_entry->io[UID_STATE_FOREGROUND].write_bytes,
- uid_entry->io[UID_STATE_BACKGROUND].rchar,
- uid_entry->io[UID_STATE_BACKGROUND].wchar,
- uid_entry->io[UID_STATE_BACKGROUND].read_bytes,
- uid_entry->io[UID_STATE_BACKGROUND].write_bytes,
- uid_entry->io[UID_STATE_FOREGROUND].fsync,
- uid_entry->io[UID_STATE_BACKGROUND].fsync);
- }
-
- rt_mutex_unlock(&uid_lock);
-
- return 0;
-}
-
-static int uid_io_open(struct inode *inode, struct file *file)
-{
- return single_open(file, uid_io_show, PDE_DATA(inode));
-}
-
-static const struct file_operations uid_io_fops = {
- .open = uid_io_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static int uid_procstat_open(struct inode *inode, struct file *file)
-{
- return single_open(file, NULL, NULL);
-}
-
-static ssize_t uid_procstat_write(struct file *file,
- const char __user *buffer, size_t count, loff_t *ppos)
-{
- struct uid_entry *uid_entry;
- uid_t uid;
- int argc, state;
- char input[128];
-
- if (count >= sizeof(input))
- return -EINVAL;
-
- if (copy_from_user(input, buffer, count))
- return -EFAULT;
-
- input[count] = '\0';
-
- argc = sscanf(input, "%u %d", &uid, &state);
- if (argc != 2)
- return -EINVAL;
-
- if (state != UID_STATE_BACKGROUND && state != UID_STATE_FOREGROUND)
- return -EINVAL;
-
- rt_mutex_lock(&uid_lock);
-
- uid_entry = find_or_register_uid(uid);
- if (!uid_entry) {
- rt_mutex_unlock(&uid_lock);
- return -EINVAL;
- }
-
- if (uid_entry->state == state) {
- rt_mutex_unlock(&uid_lock);
- return count;
- }
-
- update_io_stats_uid_locked(uid_entry);
-
- uid_entry->state = state;
-
- rt_mutex_unlock(&uid_lock);
-
- return count;
-}
-
-static const struct file_operations uid_procstat_fops = {
- .open = uid_procstat_open,
- .release = single_release,
- .write = uid_procstat_write,
-};
-
static int process_notifier(struct notifier_block *self,
unsigned long cmd, void *v)
{
@@ -437,7 +208,7 @@ static int process_notifier(struct notifier_block *self,
if (!task)
return NOTIFY_OK;
- rt_mutex_lock(&uid_lock);
+ mutex_lock(&uid_lock);
uid = from_kuid_munged(current_user_ns(), task_uid(task));
uid_entry = find_or_register_uid(uid);
if (!uid_entry) {
@@ -451,10 +222,8 @@ static int process_notifier(struct notifier_block *self,
uid_entry->power += task->cpu_power;
task->cpu_power = ULLONG_MAX;
- add_uid_io_stats(uid_entry, task, UID_STATE_DEAD_TASKS);
-
exit:
- rt_mutex_unlock(&uid_lock);
+ mutex_unlock(&uid_lock);
return NOTIFY_OK;
}
@@ -462,51 +231,25 @@ static struct notifier_block process_notifier_block = {
.notifier_call = process_notifier,
};
-static int __init proc_uid_sys_stats_init(void)
+static int __init proc_uid_cputime_init(void)
{
hash_init(hash_table);
- cpu_parent = proc_mkdir("uid_cputime", NULL);
- if (!cpu_parent) {
- pr_err("%s: failed to create uid_cputime proc entry\n",
- __func__);
- goto err;
+ parent = proc_mkdir("uid_cputime", NULL);
+ if (!parent) {
+ pr_err("%s: failed to create proc entry\n", __func__);
+ return -ENOMEM;
}
- proc_create_data("remove_uid_range", 0222, cpu_parent,
- &uid_remove_fops, NULL);
- proc_create_data("show_uid_stat", 0444, cpu_parent,
- &uid_cputime_fops, NULL);
-
- io_parent = proc_mkdir("uid_io", NULL);
- if (!io_parent) {
- pr_err("%s: failed to create uid_io proc entry\n",
- __func__);
- goto err;
- }
+ proc_create_data("remove_uid_range", S_IWUGO, parent, &uid_remove_fops,
+ NULL);
- proc_create_data("stats", 0444, io_parent,
- &uid_io_fops, NULL);
-
- proc_parent = proc_mkdir("uid_procstat", NULL);
- if (!proc_parent) {
- pr_err("%s: failed to create uid_procstat proc entry\n",
- __func__);
- goto err;
- }
-
- proc_create_data("set", 0222, proc_parent,
- &uid_procstat_fops, NULL);
+ proc_create_data("show_uid_stat", S_IRUGO, parent, &uid_stat_fops,
+ NULL);
profile_event_register(PROFILE_TASK_EXIT, &process_notifier_block);
return 0;
-
-err:
- remove_proc_subtree("uid_cputime", NULL);
- remove_proc_subtree("uid_io", NULL);
- remove_proc_subtree("uid_procstat", NULL);
- return -ENOMEM;
}
-early_initcall(proc_uid_sys_stats_init);
+early_initcall(proc_uid_cputime_init);
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index a4a86d42275..eab295f0f3a 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -707,12 +707,10 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev,
goto cmd_done;
}
-#ifdef CONFIG_MMC_FFU
if (idata->ic.opcode == MMC_FFU_INVOKE_OP) {
err = mmc_ffu_invoke(card, idata->buf);
goto cmd_done;
}
-#endif
cmd.opcode = idata->ic.opcode;
cmd.arg = idata->ic.arg;
diff --git a/drivers/net/can/usb/esd_usb2.c b/drivers/net/can/usb/esd_usb2.c
index d5455c76061..503f37850fb 100644
--- a/drivers/net/can/usb/esd_usb2.c
+++ b/drivers/net/can/usb/esd_usb2.c
@@ -335,7 +335,7 @@ static void esd_usb2_rx_can_msg(struct esd_usb2_net_priv *priv,
}
cf->can_id = id & ESD_IDMASK;
- cf->can_dlc = get_can_dlc(msg->msg.rx.dlc);
+ cf->can_dlc = get_can_dlc(msg->msg.rx.dlc & ~ESD_RTR);
if (id & ESD_EXTID)
cf->can_id |= CAN_EFF_FLAG;
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 5409fe876a4..69bc0a0eb42 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -905,10 +905,10 @@ static void korina_restart_task(struct work_struct *work)
DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR,
&lp->rx_dma_regs->dmasm);
- korina_free_ring(dev);
-
napi_disable(&lp->napi);
+ korina_free_ring(dev);
+
if (korina_init(dev) < 0) {
printk(KERN_ERR "%s: cannot restart device\n", dev->name);
return;
@@ -1069,12 +1069,12 @@ static int korina_close(struct net_device *dev)
tmp = tmp | DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR;
writel(tmp, &lp->rx_dma_regs->dmasm);
- korina_free_ring(dev);
-
napi_disable(&lp->napi);
cancel_work_sync(&lp->restart_task);
+ korina_free_ring(dev);
+
free_irq(lp->rx_irq, dev);
free_irq(lp->tx_irq, dev);
free_irq(lp->ovr_irq, dev);
diff --git a/drivers/net/ethernet/mellanox/mlx4/icm.c b/drivers/net/ethernet/mellanox/mlx4/icm.c
index 31d02649be4..d22482b4974 100644
--- a/drivers/net/ethernet/mellanox/mlx4/icm.c
+++ b/drivers/net/ethernet/mellanox/mlx4/icm.c
@@ -113,8 +113,13 @@ static int mlx4_alloc_icm_coherent(struct device *dev, struct scatterlist *mem,
if (!buf)
return -ENOMEM;
+ if (offset_in_page(buf)) {
+ dma_free_coherent(dev, PAGE_SIZE << order,
+ buf, sg_dma_address(mem));
+ return -ENOMEM;
+ }
+
sg_set_buf(mem, buf, PAGE_SIZE << order);
- BUG_ON(mem->offset);
sg_dma_len(mem) = PAGE_SIZE << order;
return 0;
}
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 3fb2643d05b..8c58001aff1 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -511,8 +511,6 @@ static int mlx4_slave_cap(struct mlx4_dev *dev)
return -ENOSYS;
}
- mlx4_log_num_mgm_entry_size = hca_param.log_mc_entry_sz;
-
dev->caps.hca_core_clock = hca_param.hca_core_clock;
memset(&dev_cap, 0, sizeof(dev_cap));
diff --git a/drivers/net/ethernet/msm/msm_rmnet_bam.c b/drivers/net/ethernet/msm/msm_rmnet_bam.c
index ace94a472a3..94e25db91ab 100644
--- a/drivers/net/ethernet/msm/msm_rmnet_bam.c
+++ b/drivers/net/ethernet/msm/msm_rmnet_bam.c
@@ -731,7 +731,7 @@ static int rmnet_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
break;
default:
- DBG0("[%s] error: rmnet_ioct called for unsupported cmd[%d]",
+ pr_err("[%s] error: rmnet_ioct called for unsupported cmd[%d]",
dev->name, cmd);
return -EINVAL;
}
diff --git a/drivers/net/ethernet/msm/msm_rmnet_smux.c b/drivers/net/ethernet/msm/msm_rmnet_smux.c
index b731e77b3b5..3c2cd63ddd0 100644
--- a/drivers/net/ethernet/msm/msm_rmnet_smux.c
+++ b/drivers/net/ethernet/msm/msm_rmnet_smux.c
@@ -778,7 +778,7 @@ static int rmnet_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
break;
default:
- DBG0("[%s] error: rmnet_ioct called for unsupported cmd[%d]",
+ pr_err("[%s] error: rmnet_ioct called for unsupported cmd[%d]",
dev->name, cmd);
return -EINVAL;
}
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c b/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c
index 10093f0c4c0..00a80587b47 100644
--- a/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c
+++ b/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c
@@ -724,7 +724,7 @@ static void ql_build_coredump_seg_header(
seg_hdr->cookie = MPI_COREDUMP_COOKIE;
seg_hdr->segNum = seg_number;
seg_hdr->segSize = seg_size;
- memcpy(seg_hdr->description, desc, (sizeof(seg_hdr->description)) - 1);
+ strncpy(seg_hdr->description, desc, (sizeof(seg_hdr->description)) - 1);
}
/*
diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
index b7268b3dae7..5f5f84ad069 100644
--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
@@ -398,7 +398,7 @@ static int xemaclite_send_data(struct net_local *drvdata, u8 *data,
*
* Return: Total number of bytes received
*/
-static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data)
+static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data, int maxlen)
{
void __iomem *addr;
u16 length, proto_type;
@@ -438,7 +438,7 @@ static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data)
/* Check if received ethernet frame is a raw ethernet frame
* or an IP packet or an ARP packet */
- if (proto_type > (ETH_FRAME_LEN + ETH_FCS_LEN)) {
+ if (proto_type > ETH_DATA_LEN) {
if (proto_type == ETH_P_IP) {
length = ((ntohl(in_be32(addr +
@@ -446,6 +446,7 @@ static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data)
XEL_RXBUFF_OFFSET)) >>
XEL_HEADER_SHIFT) &
XEL_RPLR_LENGTH_MASK);
+ length = min_t(u16, length, ETH_DATA_LEN);
length += ETH_HLEN + ETH_FCS_LEN;
} else if (proto_type == ETH_P_ARP)
@@ -458,6 +459,9 @@ static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data)
/* Use the length in the frame, plus the header and trailer */
length = proto_type + ETH_HLEN + ETH_FCS_LEN;
+ if (WARN_ON(length > maxlen))
+ length = maxlen;
+
/* Read from the EmacLite device */
xemaclite_aligned_read((u32 __force *) (addr + XEL_RXBUFF_OFFSET),
data, length);
@@ -632,7 +636,7 @@ static void xemaclite_rx_handler(struct net_device *dev)
skb_reserve(skb, 2);
- len = xemaclite_recv_data(lp, (u8 *) skb->data);
+ len = xemaclite_recv_data(lp, (u8 *) skb->data, len);
if (!len) {
dev->stats.rx_errors++;
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 202fe1ff198..b23f36a5b0d 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -656,8 +656,6 @@ static int marvell_read_status(struct phy_device *phydev)
if (adv < 0)
return adv;
- lpa &= adv;
-
if (status & MII_M1011_PHY_STATUS_FULLDUPLEX)
phydev->duplex = DUPLEX_FULL;
else
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index db49e0b84dc..bd245c3039e 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -458,7 +458,7 @@ void phy_start_machine(struct phy_device *phydev,
{
phydev->adjust_state = handler;
- queue_delayed_work(system_power_efficient_wq, &phydev->state_queue, HZ);
+ schedule_delayed_work(&phydev->state_queue, HZ);
}
/**
@@ -519,7 +519,7 @@ static irqreturn_t phy_interrupt(int irq, void *phy_dat)
disable_irq_nosync(irq);
atomic_inc(&phydev->irq_disable);
- queue_work(system_power_efficient_wq, &phydev->phy_queue);
+ schedule_work(&phydev->phy_queue);
return IRQ_HANDLED;
}
@@ -674,7 +674,7 @@ static void phy_change(struct work_struct *work)
/* reschedule state queue work to run as soon as possible */
cancel_delayed_work_sync(&phydev->state_queue);
- queue_delayed_work(system_power_efficient_wq, &phydev->state_queue, 0);
+ schedule_delayed_work(&phydev->state_queue, 0);
return;
@@ -937,8 +937,7 @@ void phy_state_machine(struct work_struct *work)
if (err < 0)
phy_error(phydev);
- queue_delayed_work(system_power_efficient_wq, &phydev->state_queue,
- PHY_STATE_TIME * HZ);
+ schedule_delayed_work(&phydev->state_queue, PHY_STATE_TIME * HZ);
}
static inline void mmd_phy_indirect(struct mii_bus *bus, int prtad, int devad,
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 5225d4321e7..0a3ad7ba2be 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -2121,8 +2121,10 @@ start_again:
hdr = genlmsg_put(skb, portid, seq, &team_nl_family, flags | NLM_F_MULTI,
TEAM_CMD_OPTIONS_GET);
- if (!hdr)
+ if (!hdr) {
+ nlmsg_free(skb);
return -EMSGSIZE;
+ }
if (nla_put_u32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex))
goto nla_put_failure;
@@ -2389,8 +2391,10 @@ start_again:
hdr = genlmsg_put(skb, portid, seq, &team_nl_family, flags | NLM_F_MULTI,
TEAM_CMD_PORT_LIST_GET);
- if (!hdr)
+ if (!hdr) {
+ nlmsg_free(skb);
return -EMSGSIZE;
+ }
if (nla_put_u32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex))
goto nla_put_failure;
diff --git a/drivers/net/wireless/cnss/cnss_pci.c b/drivers/net/wireless/cnss/cnss_pci.c
index bb43dec6bd1..8e82c147916 100644
--- a/drivers/net/wireless/cnss/cnss_pci.c
+++ b/drivers/net/wireless/cnss/cnss_pci.c
@@ -149,7 +149,6 @@ static DEFINE_SPINLOCK(pci_link_down_lock);
#define FW_IMAGE_MISSION (0x02)
#define FW_IMAGE_BDATA (0x03)
#define FW_IMAGE_PRINT (0x04)
-#define FW_SETUP_DELAY 2000
#define SEG_METADATA (0x01)
#define SEG_NON_PAGED (0x02)
@@ -270,10 +269,8 @@ static struct cnss_data {
u32 fw_dma_size;
u32 fw_seg_count;
struct segment_memory fw_seg_mem[MAX_NUM_OF_SEGMENTS];
- atomic_t fw_store_in_progress;
/* Firmware setup complete lock */
struct mutex fw_setup_stat_lock;
- struct completion fw_setup_complete;
void *bdata_cpu;
dma_addr_t bdata_dma;
u32 bdata_dma_size;
@@ -1187,15 +1184,6 @@ int cnss_get_fw_image(struct image_desc_info *image_desc_info)
!penv->fw_seg_count || !penv->bdata_seg_count)
return -EINVAL;
- /* Check for firmware setup trigger by usersapce is in progress
- * and wait for complition of firmware setup.
- */
-
- if (atomic_read(&penv->fw_store_in_progress)) {
- wait_for_completion_timeout(&penv->fw_setup_complete,
- msecs_to_jiffies(FW_SETUP_DELAY));
- }
-
mutex_lock(&penv->fw_setup_stat_lock);
image_desc_info->fw_addr = penv->fw_dma;
image_desc_info->fw_size = penv->fw_dma_size;
@@ -1293,7 +1281,9 @@ static int cnss_wlan_pci_probe(struct pci_dev *pdev,
goto err_pcie_suspend;
}
+ mutex_lock(&penv->fw_setup_stat_lock);
cnss_wlan_fw_mem_alloc(pdev);
+ mutex_unlock(&penv->fw_setup_stat_lock);
ret = device_create_file(&penv->pldev->dev, &dev_attr_wlan_setup);
@@ -1546,17 +1536,11 @@ static ssize_t fw_image_setup_store(struct device *dev,
if (!penv)
return -ENODEV;
- if (atomic_read(&penv->fw_store_in_progress)) {
- pr_info("%s: Firmware setup in progress\n", __func__);
- return 0;
- }
-
- atomic_set(&penv->fw_store_in_progress, 1);
- init_completion(&penv->fw_setup_complete);
+ mutex_lock(&penv->fw_setup_stat_lock);
+ pr_info("%s: Firmware setup in progress\n", __func__);
if (kstrtoint(buf, 0, &val)) {
- atomic_set(&penv->fw_store_in_progress, 0);
- complete(&penv->fw_setup_complete);
+ mutex_unlock(&penv->fw_setup_stat_lock);
return -EINVAL;
}
@@ -1567,8 +1551,7 @@ static ssize_t fw_image_setup_store(struct device *dev,
if (ret != 0) {
pr_err("%s: Invalid parsing of FW image files %d",
__func__, ret);
- atomic_set(&penv->fw_store_in_progress, 0);
- complete(&penv->fw_setup_complete);
+ mutex_unlock(&penv->fw_setup_stat_lock);
return -EINVAL;
}
penv->fw_image_setup = val;
@@ -1578,9 +1561,8 @@ static ssize_t fw_image_setup_store(struct device *dev,
penv->bmi_test = val;
}
- atomic_set(&penv->fw_store_in_progress, 0);
- complete(&penv->fw_setup_complete);
-
+ pr_info("%s: Firmware setup completed\n", __func__);
+ mutex_unlock(&penv->fw_setup_stat_lock);
return count;
}
@@ -1665,17 +1647,21 @@ int cnss_get_codeswap_struct(struct codeswap_codeseg_info *swap_seg)
{
struct codeswap_codeseg_info *cnss_seg_info = penv->cnss_seg_info;
+ mutex_lock(&penv->fw_setup_stat_lock);
if (!cnss_seg_info) {
swap_seg = NULL;
+ mutex_unlock(&penv->fw_setup_stat_lock);
return -ENOENT;
}
if (!atomic_read(&penv->fw_available)) {
pr_debug("%s: fw is not available\n", __func__);
+ mutex_unlock(&penv->fw_setup_stat_lock);
return -ENOENT;
}
*swap_seg = *cnss_seg_info;
+ mutex_unlock(&penv->fw_setup_stat_lock);
return 0;
}
@@ -1694,15 +1680,6 @@ static void cnss_wlan_memory_expansion(void)
u_int32_t total_length = 0;
struct pci_dev *pdev;
- /* Check for firmware setup trigger by usersapce is in progress
- * and wait for complition of firmware setup.
- */
-
- if (atomic_read(&penv->fw_store_in_progress)) {
- wait_for_completion_timeout(&penv->fw_setup_complete,
- msecs_to_jiffies(FW_SETUP_DELAY));
- }
-
mutex_lock(&penv->fw_setup_stat_lock);
pdev = penv->pdev;
dev = &pdev->dev;
@@ -2447,6 +2424,7 @@ static int cnss_probe(struct platform_device *pdev)
penv->vreg_info.wlan_reg = NULL;
penv->vreg_info.state = VREG_OFF;
penv->pci_register_again = false;
+ mutex_init(&penv->fw_setup_stat_lock);
ret = cnss_wlan_get_resources(pdev);
if (ret)
@@ -2602,8 +2580,6 @@ skip_ramdump:
memset(phys_to_virt(0), 0, SZ_4K);
#endif
- atomic_set(&penv->fw_store_in_progress, 0);
- mutex_init(&penv->fw_setup_stat_lock);
ret = device_create_file(dev, &dev_attr_fw_image_setup);
if (ret) {
pr_err("cnss: fw_image_setup sys file creation failed\n");
diff --git a/drivers/platform/msm/ipa/ipa.c b/drivers/platform/msm/ipa/ipa.c
index ca9ff0ac711..59615c4c847 100644
--- a/drivers/platform/msm/ipa/ipa.c
+++ b/drivers/platform/msm/ipa/ipa.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015, 2017 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/platform/msm/ipa/ipa_flt.c b/drivers/platform/msm/ipa/ipa_flt.c
index b179737c318..4e2119b9715 100644
--- a/drivers/platform/msm/ipa/ipa_flt.c
+++ b/drivers/platform/msm/ipa/ipa_flt.c
@@ -1023,7 +1023,7 @@ static int __ipa_add_flt_rule(struct ipa_flt_tbl *tbl, enum ipa_ip_type ip,
goto error;
}
- if (rt_tbl->cookie != IPA_COOKIE) {
+ if (rt_tbl->cookie != IPA_RT_TBL_COOKIE) {
IPAERR("RT table cookie is invalid\n");
goto error;
}
@@ -1044,7 +1044,7 @@ static int __ipa_add_flt_rule(struct ipa_flt_tbl *tbl, enum ipa_ip_type ip,
}
INIT_LIST_HEAD(&entry->link);
entry->rule = *rule;
- entry->cookie = IPA_COOKIE;
+ entry->cookie = IPA_FLT_COOKIE;
entry->rt_tbl = rt_tbl;
entry->tbl = tbl;
if (add_rear) {
@@ -1063,13 +1063,19 @@ static int __ipa_add_flt_rule(struct ipa_flt_tbl *tbl, enum ipa_ip_type ip,
if (id < 0) {
IPAERR("failed to add to tree\n");
WARN_ON(1);
+ goto ipa_insert_failed;
}
*rule_hdl = id;
entry->id = id;
IPADBG("add flt rule rule_cnt=%d\n", tbl->rule_cnt);
return 0;
-
+ipa_insert_failed:
+ tbl->rule_cnt--;
+ if (entry->rt_tbl)
+ entry->rt_tbl->ref_cnt--;
+ list_del(&entry->link);
+ kmem_cache_free(ipa_ctx->flt_rule_cache, entry);
error:
return -EPERM;
}
@@ -1085,7 +1091,7 @@ static int __ipa_del_flt_rule(u32 rule_hdl)
return -EINVAL;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_FLT_COOKIE) {
IPAERR("bad params\n");
return -EINVAL;
}
@@ -1117,7 +1123,7 @@ static int __ipa_mdfy_flt_rule(struct ipa_flt_rule_mdfy *frule,
goto error;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_FLT_COOKIE) {
IPAERR("bad params\n");
goto error;
}
@@ -1138,7 +1144,7 @@ static int __ipa_mdfy_flt_rule(struct ipa_flt_rule_mdfy *frule,
goto error;
}
- if (rt_tbl->cookie != IPA_COOKIE) {
+ if (rt_tbl->cookie != IPA_RT_TBL_COOKIE) {
IPAERR("RT table cookie is invalid\n");
goto error;
}
diff --git a/drivers/platform/msm/ipa/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_hdr.c
index f4cd470d22a..f0614e323c2 100644
--- a/drivers/platform/msm/ipa/ipa_hdr.c
+++ b/drivers/platform/msm/ipa/ipa_hdr.c
@@ -480,7 +480,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
{
struct ipa_hdr_entry *hdr_entry;
struct ipa_hdr_proc_ctx_entry *entry;
- struct ipa_hdr_proc_ctx_offset_entry *offset;
+ struct ipa_hdr_proc_ctx_offset_entry *offset = NULL;
u32 bin;
struct ipa_hdr_proc_ctx_tbl *htbl = &ipa_ctx->hdr_proc_ctx_tbl;
int id;
@@ -495,7 +495,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
}
hdr_entry = ipa_id_find(proc_ctx->hdr_hdl);
- if (!hdr_entry || (hdr_entry->cookie != IPA_COOKIE)) {
+ if (!hdr_entry || (hdr_entry->cookie != IPA_HDR_COOKIE)) {
IPAERR("hdr_hdl is invalid\n");
return -EINVAL;
}
@@ -512,7 +512,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
entry->hdr = hdr_entry;
if (add_ref_hdr)
hdr_entry->ref_cnt++;
- entry->cookie = IPA_COOKIE;
+ entry->cookie = IPA_PROC_HDR_COOKIE;
needed_len = (proc_ctx->type == IPA_HDR_PROC_NONE) ?
sizeof(struct ipa_hdr_proc_ctx_add_hdr_seq) :
@@ -564,6 +564,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
if (id < 0) {
IPAERR("failed to alloc id\n");
WARN_ON(1);
+ goto ipa_insert_failed;
}
entry->id = id;
proc_ctx->proc_ctx_hdl = id;
@@ -571,6 +572,13 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
return 0;
+ipa_insert_failed:
+ if (offset)
+ list_move(&offset->link,
+ &htbl->head_free_offset_list[offset->bin]);
+ entry->offset_entry = NULL;
+ list_del(&entry->link);
+ htbl->proc_ctx_cnt--;
bad_len:
hdr_entry->ref_cnt--;
entry->cookie = 0;
@@ -582,7 +590,7 @@ bad_len:
static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
{
struct ipa_hdr_entry *entry;
- struct ipa_hdr_offset_entry *offset;
+ struct ipa_hdr_offset_entry *offset = NULL;
u32 bin;
struct ipa_hdr_tbl *htbl = &ipa_ctx->hdr_tbl;
int id;
@@ -613,7 +621,7 @@ static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
entry->type = hdr->type;
entry->is_eth2_ofst_valid = hdr->is_eth2_ofst_valid;
entry->eth2_ofst = hdr->eth2_ofst;
- entry->cookie = IPA_COOKIE;
+ entry->cookie = IPA_HDR_COOKIE;
if (hdr->hdr_len <= ipa_hdr_bin_sz[IPA_HDR_BIN0])
bin = IPA_HDR_BIN0;
@@ -696,6 +704,7 @@ static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
if (id < 0) {
IPAERR("failed to alloc id\n");
WARN_ON(1);
+ goto ipa_insert_failed;
}
entry->id = id;
hdr->hdr_hdl = id;
@@ -720,10 +729,19 @@ fail_add_proc_ctx:
entry->ref_cnt--;
hdr->hdr_hdl = 0;
ipa_id_remove(id);
+ipa_insert_failed:
+ if (entry->is_hdr_proc_ctx) {
+ dma_unmap_single(ipa_ctx->pdev, entry->phys_base,
+ entry->hdr_len, DMA_TO_DEVICE);
+ } else {
+ if (offset)
+ list_move(&offset->link,
+ &htbl->head_free_offset_list[offset->bin]);
+ entry->offset_entry = NULL;
+ }
+
htbl->hdr_cnt--;
list_del(&entry->link);
- dma_unmap_single(ipa_ctx->pdev, entry->phys_base,
- entry->hdr_len, DMA_TO_DEVICE);
bad_hdr_len:
entry->cookie = 0;
kmem_cache_free(ipa_ctx->hdr_cache, entry);
@@ -738,7 +756,7 @@ static int __ipa_del_hdr_proc_ctx(u32 proc_ctx_hdl,
struct ipa_hdr_proc_ctx_tbl *htbl = &ipa_ctx->hdr_proc_ctx_tbl;
entry = ipa_id_find(proc_ctx_hdl);
- if (!entry || (entry->cookie != IPA_COOKIE)) {
+ if (!entry || (entry->cookie != IPA_PROC_HDR_COOKIE)) {
IPAERR("bad parm\n");
return -EINVAL;
}
@@ -789,7 +807,7 @@ int __ipa_del_hdr(u32 hdr_hdl, bool by_user)
return -EINVAL;
}
- if (!entry || (entry->cookie != IPA_COOKIE)) {
+ if (!entry || (entry->cookie != IPA_HDR_COOKIE)) {
IPAERR("bad parm\n");
return -EINVAL;
}
@@ -1354,7 +1372,7 @@ int ipa_put_hdr(u32 hdr_hdl)
goto bail;
}
- if (entry == NULL || entry->cookie != IPA_COOKIE) {
+ if (entry == NULL || entry->cookie != IPA_HDR_COOKIE) {
IPAERR("bad params\n");
result = -EINVAL;
goto bail;
diff --git a/drivers/platform/msm/ipa/ipa_i.h b/drivers/platform/msm/ipa/ipa_i.h
index 2ea952c8bd8..0d12d17dcb4 100644
--- a/drivers/platform/msm/ipa/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_i.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015, 2017 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -33,6 +33,12 @@
#define DRV_NAME "ipa"
#define NAT_DEV_NAME "ipaNatTable"
#define IPA_COOKIE 0x57831603
+#define IPA_RT_RULE_COOKIE 0x57831604
+#define IPA_RT_TBL_COOKIE 0x57831605
+#define IPA_FLT_COOKIE 0x57831606
+#define IPA_HDR_COOKIE 0x57831607
+#define IPA_PROC_HDR_COOKIE 0x57831608
+
#define MTU_BYTE 1500
#define IPA_MAX_NUM_PIPES 0x14
@@ -183,8 +189,8 @@ struct ipa_mem_buffer {
*/
struct ipa_flt_entry {
struct list_head link;
- struct ipa_flt_rule rule;
u32 cookie;
+ struct ipa_flt_rule rule;
struct ipa_flt_tbl *tbl;
struct ipa_rt_tbl *rt_tbl;
u32 hw_len;
@@ -209,13 +215,13 @@ struct ipa_flt_entry {
*/
struct ipa_rt_tbl {
struct list_head link;
+ u32 cookie;
struct list_head head_rt_rule_list;
char name[IPA_RESOURCE_NAME_MAX];
u32 idx;
u32 rule_cnt;
u32 ref_cnt;
struct ipa_rt_tbl_set *set;
- u32 cookie;
bool in_sys;
u32 sz;
struct ipa_mem_buffer curr_mem;
@@ -246,6 +252,7 @@ struct ipa_rt_tbl {
*/
struct ipa_hdr_entry {
struct list_head link;
+ u32 cookie;
u8 hdr[IPA_HDR_MAX_SIZE];
u32 hdr_len;
char name[IPA_RESOURCE_NAME_MAX];
@@ -255,7 +262,6 @@ struct ipa_hdr_entry {
dma_addr_t phys_base;
struct ipa_hdr_proc_ctx_entry *proc_ctx;
struct ipa_hdr_offset_entry *offset_entry;
- u32 cookie;
u32 ref_cnt;
int id;
u8 is_eth2_ofst_valid;
@@ -340,10 +346,10 @@ struct ipa_hdr_proc_ctx_add_hdr_cmd_seq {
*/
struct ipa_hdr_proc_ctx_entry {
struct list_head link;
+ u32 cookie;
enum ipa_hdr_proc_type type;
struct ipa_hdr_proc_ctx_offset_entry *offset_entry;
struct ipa_hdr_entry *hdr;
- u32 cookie;
u32 ref_cnt;
int id;
bool user_deleted;
@@ -399,8 +405,8 @@ struct ipa_flt_tbl {
*/
struct ipa_rt_entry {
struct list_head link;
- struct ipa_rt_rule rule;
u32 cookie;
+ struct ipa_rt_rule rule;
struct ipa_rt_tbl *tbl;
struct ipa_hdr_entry *hdr;
struct ipa_hdr_proc_ctx_entry *proc_ctx;
diff --git a/drivers/platform/msm/ipa/ipa_rt.c b/drivers/platform/msm/ipa/ipa_rt.c
index 87a88dc6aaa..e5786ffa270 100644
--- a/drivers/platform/msm/ipa/ipa_rt.c
+++ b/drivers/platform/msm/ipa/ipa_rt.c
@@ -880,7 +880,7 @@ static struct ipa_rt_tbl *__ipa_add_rt_tbl(enum ipa_ip_type ip,
INIT_LIST_HEAD(&entry->link);
strlcpy(entry->name, name, IPA_RESOURCE_NAME_MAX);
entry->set = set;
- entry->cookie = IPA_COOKIE;
+ entry->cookie = IPA_RT_TBL_COOKIE;
entry->in_sys = (ip == IPA_IP_v4) ?
!ipa_ctx->ip4_rt_tbl_lcl : !ipa_ctx->ip6_rt_tbl_lcl;
set->tbl_cnt++;
@@ -893,12 +893,16 @@ static struct ipa_rt_tbl *__ipa_add_rt_tbl(enum ipa_ip_type ip,
if (id < 0) {
IPAERR("failed to add to tree\n");
WARN_ON(1);
+ goto ipa_insert_failed;
}
entry->id = id;
}
return entry;
+ipa_insert_failed:
+ set->tbl_cnt--;
+ list_del(&entry->link);
fail_rt_idx_alloc:
entry->cookie = 0;
kmem_cache_free(ipa_ctx->rt_tbl_cache, entry);
@@ -911,7 +915,7 @@ static int __ipa_del_rt_tbl(struct ipa_rt_tbl *entry)
enum ipa_ip_type ip = IPA_IP_MAX;
u32 id;
- if (entry == NULL || (entry->cookie != IPA_COOKIE)) {
+ if (entry == NULL || (entry->cookie != IPA_RT_TBL_COOKIE)) {
IPAERR("bad parms\n");
return -EINVAL;
}
@@ -925,8 +929,10 @@ static int __ipa_del_rt_tbl(struct ipa_rt_tbl *entry)
ip = IPA_IP_v4;
else if (entry->set == &ipa_ctx->rt_tbl_set[IPA_IP_v6])
ip = IPA_IP_v6;
- else
+ else {
WARN_ON(1);
+ return -EPERM;
+ }
if (!entry->in_sys) {
list_del(&entry->link);
@@ -965,13 +971,14 @@ static int __ipa_add_rt_rule(enum ipa_ip_type ip, const char *name,
if (rule->hdr_hdl) {
hdr = ipa_id_find(rule->hdr_hdl);
- if ((hdr == NULL) || (hdr->cookie != IPA_COOKIE)) {
+ if ((hdr == NULL) || (hdr->cookie != IPA_HDR_COOKIE)) {
IPAERR("rt rule does not point to valid hdr\n");
goto error;
}
} else if (rule->hdr_proc_ctx_hdl) {
proc_ctx = ipa_id_find(rule->hdr_proc_ctx_hdl);
- if ((proc_ctx == NULL) || (proc_ctx->cookie != IPA_COOKIE)) {
+ if ((proc_ctx == NULL) ||
+ (proc_ctx->cookie != IPA_PROC_HDR_COOKIE)) {
IPAERR("rt rule does not point to valid proc ctx\n");
goto error;
}
@@ -979,7 +986,7 @@ static int __ipa_add_rt_rule(enum ipa_ip_type ip, const char *name,
tbl = __ipa_add_rt_tbl(ip, name);
- if (tbl == NULL || (tbl->cookie != IPA_COOKIE)) {
+ if (tbl == NULL || (tbl->cookie != IPA_RT_TBL_COOKIE)) {
IPAERR("bad params\n");
goto error;
}
@@ -1000,7 +1007,7 @@ static int __ipa_add_rt_rule(enum ipa_ip_type ip, const char *name,
goto error;
}
INIT_LIST_HEAD(&entry->link);
- entry->cookie = IPA_COOKIE;
+ entry->cookie = IPA_RT_RULE_COOKIE;
entry->rule = *rule;
entry->tbl = tbl;
entry->hdr = hdr;
@@ -1090,7 +1097,7 @@ int __ipa_del_rt_rule(u32 rule_hdl)
return -EINVAL;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_RT_RULE_COOKIE) {
IPAERR("bad params\n");
return -EINVAL;
}
@@ -1328,7 +1335,7 @@ int ipa_get_rt_tbl(struct ipa_ioc_get_rt_tbl *lookup)
}
mutex_lock(&ipa_ctx->lock);
entry = __ipa_find_rt_tbl(lookup->ip, lookup->name);
- if (entry && entry->cookie == IPA_COOKIE) {
+ if (entry && entry->cookie == IPA_RT_TBL_COOKIE) {
entry->ref_cnt++;
lookup->hdl = entry->id;
@@ -1366,7 +1373,7 @@ int ipa_put_rt_tbl(u32 rt_tbl_hdl)
goto ret;
}
- if ((entry->cookie != IPA_COOKIE) || entry->ref_cnt == 0) {
+ if ((entry->cookie != IPA_RT_TBL_COOKIE) || entry->ref_cnt == 0) {
IPAERR("bad parms\n");
result = -EINVAL;
goto ret;
@@ -1376,8 +1383,11 @@ int ipa_put_rt_tbl(u32 rt_tbl_hdl)
ip = IPA_IP_v4;
else if (entry->set == &ipa_ctx->rt_tbl_set[IPA_IP_v6])
ip = IPA_IP_v6;
- else
+ else {
WARN_ON(1);
+ result = -EINVAL;
+ goto ret;
+ }
entry->ref_cnt--;
if (entry->ref_cnt == 0 && entry->rule_cnt == 0) {
@@ -1405,7 +1415,7 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule)
if (rtrule->rule.hdr_hdl) {
hdr = ipa_id_find(rtrule->rule.hdr_hdl);
- if ((hdr == NULL) || (hdr->cookie != IPA_COOKIE)) {
+ if ((hdr == NULL) || (hdr->cookie != IPA_HDR_COOKIE)) {
IPAERR("rt rule does not point to valid hdr\n");
goto error;
}
@@ -1417,7 +1427,7 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule)
goto error;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_RT_RULE_COOKIE) {
IPAERR("bad params\n");
goto error;
}
diff --git a/drivers/platform/msm/ipa/rmnet_ipa.c b/drivers/platform/msm/ipa/rmnet_ipa.c
index 7d3b5554f6e..d7f4b043d50 100644
--- a/drivers/platform/msm/ipa/rmnet_ipa.c
+++ b/drivers/platform/msm/ipa/rmnet_ipa.c
@@ -68,6 +68,7 @@ static void *subsys_notify_handle;
u32 apps_to_ipa_hdl, ipa_to_apps_hdl; /* get handler from ipa */
static struct mutex ipa_to_apps_pipe_handle_guard;
+static struct mutex add_mux_channel_lock;
static int wwan_add_ul_flt_rule_to_ipa(void);
static int wwan_del_ul_flt_rule_to_ipa(void);
static void ipa_wwan_msg_free_cb(void*, u32, u32);
@@ -1345,9 +1346,11 @@ static int ipa_wwan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
rmnet_mux_val.mux_id);
return rc;
}
+ mutex_lock(&add_mux_channel_lock);
if (rmnet_index >= MAX_NUM_OF_MUX_CHANNEL) {
IPAWANERR("Exceed mux_channel limit(%d)\n",
rmnet_index);
+ mutex_unlock(&add_mux_channel_lock);
return -EFAULT;
}
IPAWANDBG("ADD_MUX_CHANNEL(%d, name: %s)\n",
@@ -1375,6 +1378,7 @@ static int ipa_wwan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
IPAWANERR("device %s reg IPA failed\n",
extend_ioctl_data.u.
rmnet_mux_val.vchannel_name);
+ mutex_unlock(&add_mux_channel_lock);
return -ENODEV;
}
mux_channel[rmnet_index].mux_channel_set = true;
@@ -1387,6 +1391,7 @@ static int ipa_wwan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
mux_channel[rmnet_index].ul_flt_reg = false;
}
rmnet_index++;
+ mutex_unlock(&add_mux_channel_lock);
break;
case RMNET_IOCTL_SET_EGRESS_DATA_FORMAT:
IPAWANDBG("get RMNET_IOCTL_SET_EGRESS_DATA_FORMAT\n");
@@ -2710,6 +2715,7 @@ static int __init ipa_wwan_init(void)
mutex_init(&ipa_to_apps_pipe_handle_guard);
ipa_to_apps_hdl = -1;
+ mutex_init(&add_mux_channel_lock);
ipa_qmi_init();
@@ -2720,19 +2726,21 @@ static int __init ipa_wwan_init(void)
return platform_driver_register(&rmnet_ipa_driver);
else
return (int)PTR_ERR(subsys_notify_handle);
- }
+}
static void __exit ipa_wwan_cleanup(void)
{
int ret;
ipa_qmi_cleanup();
mutex_destroy(&ipa_to_apps_pipe_handle_guard);
+ mutex_destroy(&add_mux_channel_lock);
ret = subsys_notif_unregister_notifier(subsys_notify_handle,
&ssr_notifier);
if (ret)
IPAWANERR(
"Error subsys_notif_unregister_notifier system %s, ret=%d\n",
SUBSYS_MODEM, ret);
+
platform_driver_unregister(&rmnet_ipa_driver);
}
diff --git a/drivers/platform/msm/mhi/mhi_sys.c b/drivers/platform/msm/mhi/mhi_sys.c
index d57ac8c0e21..9603b6a91db 100644
--- a/drivers/platform/msm/mhi/mhi_sys.c
+++ b/drivers/platform/msm/mhi/mhi_sys.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -188,22 +188,6 @@ static const struct file_operations mhi_dbgfs_ev_fops = {
.write = NULL,
};
-static ssize_t mhi_dbgfs_trigger_msi(struct file *fp, const char __user *buf,
- size_t count, loff_t *offp)
-{
- u32 msi_nr = 0;
- void *irq_ctxt = &((mhi_devices.device_list[0]).pcie_device->dev);
- if (copy_from_user(&msi_nr, buf, sizeof(msi_nr)))
- return -ENOMEM;
- mhi_msi_handlr(msi_nr, irq_ctxt);
- return 0;
-}
-
-static const struct file_operations mhi_dbgfs_trigger_msi_fops = {
- .read = NULL,
- .write = mhi_dbgfs_trigger_msi,
-};
-
static ssize_t mhi_dbgfs_state_read(struct file *fp, char __user *buf,
size_t count, loff_t *offp)
{
@@ -303,7 +287,6 @@ int mhi_init_debugfs(struct mhi_device_ctxt *mhi_dev_ctxt)
{
struct dentry *mhi_chan_stats;
struct dentry *mhi_state_stats;
- struct dentry *mhi_msi_trigger;
struct dentry *mhi_ev_stats;
mhi_dev_ctxt->mhi_parent_folder =
debugfs_create_dir("mhi", NULL);
@@ -332,21 +315,12 @@ int mhi_init_debugfs(struct mhi_device_ctxt *mhi_dev_ctxt)
&mhi_dbgfs_state_fops);
if (mhi_state_stats == NULL)
goto clean_ev_stats;
- mhi_msi_trigger = debugfs_create_file("mhi_msi_trigger",
- 0444,
- mhi_dev_ctxt->mhi_parent_folder,
- mhi_dev_ctxt,
- &mhi_dbgfs_trigger_msi_fops);
- if (mhi_msi_trigger == NULL)
- goto clean_state;
mhi_dev_ctxt->chan_info = kmalloc(MHI_LOG_SIZE, GFP_KERNEL);
if (mhi_dev_ctxt->chan_info == NULL)
goto clean_all;
return 0;
clean_all:
- debugfs_remove(mhi_msi_trigger);
-clean_state:
debugfs_remove(mhi_state_stats);
clean_ev_stats:
debugfs_remove(mhi_ev_stats);
diff --git a/drivers/platform/msm/msm_bus/msm_bus_dbg.c b/drivers/platform/msm/msm_bus/msm_bus_dbg.c
index d7d2ff384ad..df3d39e51b4 100644
--- a/drivers/platform/msm/msm_bus/msm_bus_dbg.c
+++ b/drivers/platform/msm/msm_bus/msm_bus_dbg.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, 2014-2015, The Linux Foundation. All rights
+/* Copyright (c) 2010-2012, 2014-2015, 2017 The Linux Foundation. All rights
* reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -38,7 +38,7 @@
static struct dentry *clients;
static struct dentry *dir;
static DEFINE_MUTEX(msm_bus_dbg_fablist_lock);
-static DEFINE_MUTEX(cl_list_lock);
+static DEFINE_RT_MUTEX(msm_bus_dbg_cllist_lock);
struct msm_bus_dbg_state {
uint32_t cl;
uint8_t enable;
@@ -285,14 +285,14 @@ DEFINE_SIMPLE_ATTRIBUTE(shell_client_en_fops, msm_bus_dbg_en_get,
static ssize_t client_data_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
- ssize_t ret;
int bsize = 0;
uint32_t cl = (uint32_t)(uintptr_t)file->private_data;
struct msm_bus_cldata *cldata = NULL;
const struct msm_bus_client_handle *handle = file->private_data;
int found = 0;
+ ssize_t ret;
- mutex_lock(&cl_list_lock);
+ rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_for_each_entry(cldata, &cl_list, list) {
if ((cldata->clid == cl) ||
(cldata->handle && (cldata->handle == handle))) {
@@ -302,14 +302,15 @@ static ssize_t client_data_read(struct file *file, char __user *buf,
}
if (!found) {
- mutex_unlock(&cl_list_lock);
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
return 0;
}
bsize = cldata->size;
ret = simple_read_from_buffer(buf, count, ppos,
cldata->buffer, bsize);
- mutex_unlock(&cl_list_lock);
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
+
return ret;
}
@@ -339,16 +340,16 @@ int msm_bus_dbg_add_client(const struct msm_bus_client_handle *pdata)
{
struct msm_bus_cldata *cldata;
- mutex_lock(&cl_list_lock);
+
cldata = kzalloc(sizeof(struct msm_bus_cldata), GFP_KERNEL);
if (!cldata) {
MSM_BUS_DBG("Failed to allocate memory for client data\n");
- mutex_unlock(&cl_list_lock);
return -ENOMEM;
}
cldata->handle = pdata;
+ rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_add_tail(&cldata->list, &cl_list);
- mutex_unlock(&cl_list_lock);
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
return 0;
}
@@ -361,7 +362,7 @@ int msm_bus_dbg_rec_transaction(const struct msm_bus_client_handle *pdata,
bool found = false;
char *buf = NULL;
- mutex_lock(&cl_list_lock);
+ rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_for_each_entry(cldata, &cl_list, list) {
if (cldata->handle == pdata) {
found = true;
@@ -370,14 +371,14 @@ int msm_bus_dbg_rec_transaction(const struct msm_bus_client_handle *pdata,
}
if (!found) {
- mutex_unlock(&cl_list_lock);
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
return -ENOENT;
}
if (cldata->file == NULL) {
if (pdata->name == NULL) {
MSM_BUS_DBG("Client doesn't have a name\n");
- mutex_unlock(&cl_list_lock);
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
return -EINVAL;
}
pr_debug("\n%s setting up debugfs %s", __func__, pdata->name);
@@ -407,10 +408,11 @@ int msm_bus_dbg_rec_transaction(const struct msm_bus_client_handle *pdata,
i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "%llu ", ib);
i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "\n");
cldata->size = i;
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
trace_bus_update_request((int)ts.tv_sec, (int)ts.tv_nsec,
pdata->name, pdata->mas, pdata->slv, ab, ib);
- mutex_unlock(&cl_list_lock);
+
return i;
}
@@ -418,7 +420,7 @@ void msm_bus_dbg_remove_client(const struct msm_bus_client_handle *pdata)
{
struct msm_bus_cldata *cldata = NULL;
- mutex_lock(&cl_list_lock);
+ rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_for_each_entry(cldata, &cl_list, list) {
if (cldata->handle == pdata) {
debugfs_remove(cldata->file);
@@ -427,7 +429,7 @@ void msm_bus_dbg_remove_client(const struct msm_bus_client_handle *pdata)
break;
}
}
- mutex_unlock(&cl_list_lock);
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
}
static int msm_bus_dbg_record_client(const struct msm_bus_scale_pdata *pdata,
@@ -435,11 +437,9 @@ static int msm_bus_dbg_record_client(const struct msm_bus_scale_pdata *pdata,
{
struct msm_bus_cldata *cldata;
- mutex_lock(&cl_list_lock);
cldata = kmalloc(sizeof(struct msm_bus_cldata), GFP_KERNEL);
if (!cldata) {
MSM_BUS_DBG("Failed to allocate memory for client data\n");
- mutex_unlock(&cl_list_lock);
return -ENOMEM;
}
cldata->pdata = pdata;
@@ -447,8 +447,9 @@ static int msm_bus_dbg_record_client(const struct msm_bus_scale_pdata *pdata,
cldata->clid = clid;
cldata->file = file;
cldata->size = 0;
+ rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_add_tail(&cldata->list, &cl_list);
- mutex_unlock(&cl_list_lock);
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
return 0;
}
@@ -456,7 +457,7 @@ static void msm_bus_dbg_free_client(uint32_t clid)
{
struct msm_bus_cldata *cldata = NULL;
- mutex_lock(&cl_list_lock);
+ rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_for_each_entry(cldata, &cl_list, list) {
if (cldata->clid == clid) {
debugfs_remove(cldata->file);
@@ -465,7 +466,7 @@ static void msm_bus_dbg_free_client(uint32_t clid)
break;
}
}
- mutex_unlock(&cl_list_lock);
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
}
static int msm_bus_dbg_fill_cl_buffer(const struct msm_bus_scale_pdata *pdata,
@@ -477,7 +478,7 @@ static int msm_bus_dbg_fill_cl_buffer(const struct msm_bus_scale_pdata *pdata,
struct timespec ts;
int found = 0;
- mutex_lock(&cl_list_lock);
+ rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_for_each_entry(cldata, &cl_list, list) {
if (cldata->clid == clid) {
found = 1;
@@ -486,14 +487,14 @@ static int msm_bus_dbg_fill_cl_buffer(const struct msm_bus_scale_pdata *pdata,
}
if (!found) {
- mutex_unlock(&cl_list_lock);
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
return -ENOENT;
}
if (cldata->file == NULL) {
if (pdata->name == NULL) {
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
MSM_BUS_DBG("Client doesn't have a name\n");
- mutex_unlock(&cl_list_lock);
return -EINVAL;
}
cldata->file = msm_bus_dbg_create(pdata->name, S_IRUGO,
@@ -540,20 +541,9 @@ static int msm_bus_dbg_fill_cl_buffer(const struct msm_bus_scale_pdata *pdata,
cldata->index = index;
cldata->size = i;
- mutex_unlock(&cl_list_lock);
- return i;
-}
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
-static int msm_bus_dbg_update_request(struct msm_bus_cldata *cldata, int index)
-{
- int ret = 0;
-
- if ((index < 0) || (index > cldata->pdata->num_usecases)) {
- MSM_BUS_DBG("Invalid index!\n");
- return -EINVAL;
- }
- ret = msm_bus_scale_client_update_request(cldata->clid, index);
- return ret;
+ return i;
}
static ssize_t msm_bus_dbg_update_request_write(struct file *file,
@@ -565,20 +555,26 @@ static ssize_t msm_bus_dbg_update_request_write(struct file *file,
char *chid;
char *buf = kmalloc((sizeof(char) * (cnt + 1)), GFP_KERNEL);
int found = 0;
+ uint32_t clid;
+ ssize_t res = cnt;
if (!buf || IS_ERR(buf)) {
MSM_BUS_ERR("Memory allocation for buffer failed\n");
return -ENOMEM;
}
- if (cnt == 0)
- return 0;
- if (copy_from_user(buf, ubuf, cnt))
- return -EFAULT;
+ if (cnt == 0) {
+ res = 0;
+ goto out;
+ }
+ if (copy_from_user(buf, ubuf, cnt)) {
+ res = -EFAULT;
+ goto out;
+ }
buf[cnt] = '\0';
chid = buf;
MSM_BUS_DBG("buffer: %s\n size: %zu\n", buf, sizeof(ubuf));
- mutex_lock(&cl_list_lock);
+ rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_for_each_entry(cldata, &cl_list, list) {
if (strnstr(chid, cldata->pdata->name, cnt)) {
found = 1;
@@ -589,23 +585,35 @@ static ssize_t msm_bus_dbg_update_request_write(struct file *file,
if (ret) {
MSM_BUS_DBG("Index conversion"
" failed\n");
- mutex_unlock(&cl_list_lock);
- return -EFAULT;
+ rt_mutex_unlock(
+ &msm_bus_dbg_cllist_lock);
+ res = -EFAULT;
+ goto out;
}
} else {
MSM_BUS_DBG("Error parsing input. Index not"
" found\n");
found = 0;
}
+ if ((index < 0) ||
+ (index > cldata->pdata->num_usecases)) {
+ MSM_BUS_DBG("Invalid index!\n");
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
+ res = -EINVAL;
+ goto out;
+ }
+ clid = cldata->clid;
break;
}
}
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
if (found)
- msm_bus_dbg_update_request(cldata, index);
- mutex_unlock(&cl_list_lock);
+ msm_bus_scale_client_update_request(clid, index);
+
+out:
kfree(buf);
- return cnt;
+ return res;
}
/**
@@ -628,8 +636,10 @@ static ssize_t fabric_data_read(struct file *file, char __user *buf,
break;
}
}
- if (!found)
+ if (!found) {
+ mutex_unlock(&msm_bus_dbg_fablist_lock);
return -ENOENT;
+ }
bsize = fablist->size;
ret = simple_read_from_buffer(buf, count, ppos,
fablist->buffer, bsize);
@@ -718,8 +728,10 @@ static int msm_bus_dbg_fill_fab_buffer(const char *fabname,
break;
}
}
- if (!found)
+ if (!found) {
+ mutex_unlock(&msm_bus_dbg_fablist_lock);
return -ENOENT;
+ }
if (fablist->file == NULL) {
MSM_BUS_DBG("Fabric dbg entry does not exist\n");
@@ -770,7 +782,8 @@ static ssize_t msm_bus_dbg_dump_clients_read(struct file *file,
"\nDumping curent client votes to trace log\n");
if (*ppos)
goto exit_dump_clients_read;
- mutex_lock(&cl_list_lock);
+
+ rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_for_each_entry(cldata, &cl_list, list) {
if (IS_ERR_OR_NULL(cldata->pdata))
continue;
@@ -786,7 +799,7 @@ static ssize_t msm_bus_dbg_dump_clients_read(struct file *file,
cldata->pdata->active_only);
}
}
- mutex_unlock(&cl_list_lock);
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
exit_dump_clients_read:
return simple_read_from_buffer(buf, count, ppos, msg, cnt);
}
@@ -911,7 +924,7 @@ static int __init msm_bus_debugfs_init(void)
goto err;
}
- mutex_lock(&cl_list_lock);
+ rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_for_each_entry(cldata, &cl_list, list) {
if (cldata->pdata) {
if (cldata->pdata->name == NULL) {
@@ -931,7 +944,8 @@ static int __init msm_bus_debugfs_init(void)
&client_data_fops);
}
}
- mutex_unlock(&cl_list_lock);
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
+
if (debugfs_create_file("dump_clients", S_IRUGO | S_IWUSR,
clients, NULL, &msm_bus_dbg_dump_clients_fops) == NULL)
goto err;
@@ -943,6 +957,7 @@ static int __init msm_bus_debugfs_init(void)
if (fablist->file == NULL) {
MSM_BUS_DBG("Cannot create files for commit data\n");
kfree(rules_buf);
+ mutex_unlock(&msm_bus_dbg_fablist_lock);
goto err;
}
}
@@ -962,12 +977,13 @@ static void __exit msm_bus_dbg_teardown(void)
struct msm_bus_cldata *cldata = NULL, *cldata_temp;
debugfs_remove_recursive(dir);
- mutex_lock(&cl_list_lock);
+
+ rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_for_each_entry_safe(cldata, cldata_temp, &cl_list, list) {
list_del(&cldata->list);
kfree(cldata);
}
- mutex_unlock(&cl_list_lock);
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
mutex_lock(&msm_bus_dbg_fablist_lock);
list_for_each_entry_safe(fablist, fablist_temp, &fabdata_list, list) {
diff --git a/drivers/platform/msm/msm_bus/msm_bus_dbg_voter.c b/drivers/platform/msm/msm_bus/msm_bus_dbg_voter.c
index 594bccfaf81..a876484859e 100644
--- a/drivers/platform/msm/msm_bus/msm_bus_dbg_voter.c
+++ b/drivers/platform/msm/msm_bus/msm_bus_dbg_voter.c
@@ -137,7 +137,6 @@ static ssize_t bus_floor_vote_store_api(struct device *dev,
pr_err("%s:return error", __func__);
return -EINVAL;
}
- name[9] = '\0';
pr_info("%s: name %s vote %llu\n",
__func__, name, vote_khz);
diff --git a/drivers/power/qcom/msm-core.c b/drivers/power/qcom/msm-core.c
index f040d20a40f..f644950fe46 100644
--- a/drivers/power/qcom/msm-core.c
+++ b/drivers/power/qcom/msm-core.c
@@ -297,7 +297,7 @@ static __ref int do_sampling(void *data)
static int prev_temp[NR_CPUS];
while (!kthread_should_stop()) {
- wait_for_completion_interruptible(&sampling_completion);
+ wait_for_completion(&sampling_completion);
cancel_delayed_work(&sampling_work);
mutex_lock(&kthread_update_mutex);
@@ -319,8 +319,7 @@ static __ref int do_sampling(void *data)
if (!poll_ms)
goto unlock;
- queue_delayed_work(system_power_efficient_wq,
- &sampling_work,
+ schedule_delayed_work(&sampling_work,
msecs_to_jiffies(poll_ms));
unlock:
mutex_unlock(&kthread_update_mutex);
diff --git a/drivers/power/qpnp-fg.c b/drivers/power/qpnp-fg.c
index 634d6202cf1..94792aced42 100644
--- a/drivers/power/qpnp-fg.c
+++ b/drivers/power/qpnp-fg.c
@@ -1769,7 +1769,7 @@ static int set_prop_jeita_temp(struct fg_chip *chip,
cancel_delayed_work_sync(
&chip->update_jeita_setting);
- queue_delayed_work(system_power_efficient_wq,
+ schedule_delayed_work(
&chip->update_jeita_setting, 0);
return rc;
@@ -2085,7 +2085,7 @@ wait:
update_sram_data(chip, &resched_ms);
out:
- queue_delayed_work(system_power_efficient_wq,
+ schedule_delayed_work(
&chip->update_sram_data,
msecs_to_jiffies(resched_ms));
}
@@ -2166,11 +2166,9 @@ out:
if (rc)
pr_err("failed to write BATT_TEMP_OFF rc=%d\n", rc);
}
-
- queue_delayed_work(system_power_efficient_wq,
+ schedule_delayed_work(
&chip->update_temp_work,
msecs_to_jiffies(TEMP_PERIOD_UPDATE_MS));
-
fg_relax(&chip->update_temp_wakeup_source);
}
@@ -3317,8 +3315,7 @@ static void status_change_work(struct work_struct *work)
*/
if (chip->last_sram_update_time + 5 < current_time) {
cancel_delayed_work(&chip->update_sram_data);
- queue_delayed_work(system_power_efficient_wq,
- &chip->update_sram_data,
+ schedule_delayed_work(&chip->update_sram_data,
msecs_to_jiffies(0));
}
if (chip->cyc_ctr.en)
@@ -3814,7 +3811,7 @@ static irqreturn_t fg_batt_missing_irq_handler(int irq, void *_chip)
INIT_COMPLETION(chip->batt_id_avail);
schedule_work(&chip->batt_profile_init);
cancel_delayed_work(&chip->update_sram_data);
- queue_delayed_work(system_power_efficient_wq,
+ schedule_delayed_work(
&chip->update_sram_data,
msecs_to_jiffies(0));
} else {
@@ -3926,8 +3923,7 @@ static irqreturn_t fg_empty_soc_irq_handler(int irq, void *_chip)
if (soc_rt_sts & SOC_EMPTY) {
chip->soc_empty = true;
fg_stay_awake(&chip->empty_check_wakeup_source);
- queue_delayed_work(system_power_efficient_wq,
- &chip->check_empty_work,
+ schedule_delayed_work(&chip->check_empty_work,
msecs_to_jiffies(FG_EMPTY_DEBOUNCE_MS));
} else {
chip->soc_empty = false;
@@ -6149,7 +6145,7 @@ static void delayed_init_work(struct work_struct *work)
/* release memory access before update_sram_data is called */
fg_mem_release(chip);
- queue_delayed_work(system_power_efficient_wq,
+ schedule_delayed_work(
&chip->update_jeita_setting,
msecs_to_jiffies(INIT_JEITA_DELAY_MS));
@@ -6479,7 +6475,7 @@ static void check_and_update_sram_data(struct fg_chip *chip)
else
time_left = 0;
- queue_delayed_work(system_power_efficient_wq,
+ schedule_delayed_work(
&chip->update_temp_work, msecs_to_jiffies(time_left * 1000));
next_update_time = chip->last_sram_update_time
@@ -6490,7 +6486,7 @@ static void check_and_update_sram_data(struct fg_chip *chip)
else
time_left = 0;
- queue_delayed_work(system_power_efficient_wq,
+ schedule_delayed_work(
&chip->update_sram_data, msecs_to_jiffies(time_left * 1000));
}
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 6f6eed8dce7..5fe1cbaf581 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1935,9 +1935,8 @@ int regulator_disable_deferred(struct regulator *regulator, int ms)
rdev->deferred_disables++;
mutex_unlock(&rdev->mutex);
- ret = queue_delayed_work(system_power_efficient_wq,
- &rdev->disable_work,
- msecs_to_jiffies(ms));
+ ret = schedule_delayed_work(&rdev->disable_work,
+ msecs_to_jiffies(ms));
if (ret < 0)
return ret;
else
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index bf13e73ecab..0f3581b7a2e 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -556,19 +556,32 @@ void zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd *sc,
if (fsf) {
rec->fsf_req_id = fsf->req_id;
+ rec->pl_len = FCP_RESP_WITH_EXT;
fcp_rsp = (struct fcp_resp_with_ext *)
&(fsf->qtcb->bottom.io.fcp_rsp);
+ /* mandatory parts of FCP_RSP IU in this SCSI record */
memcpy(&rec->fcp_rsp, fcp_rsp, FCP_RESP_WITH_EXT);
if (fcp_rsp->resp.fr_flags & FCP_RSP_LEN_VAL) {
fcp_rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1];
rec->fcp_rsp_info = fcp_rsp_info->rsp_code;
+ rec->pl_len += be32_to_cpu(fcp_rsp->ext.fr_rsp_len);
}
if (fcp_rsp->resp.fr_flags & FCP_SNS_LEN_VAL) {
- rec->pl_len = min((u16)SCSI_SENSE_BUFFERSIZE,
- (u16)ZFCP_DBF_PAY_MAX_REC);
- zfcp_dbf_pl_write(dbf, sc->sense_buffer, rec->pl_len,
- "fcp_sns", fsf->req_id);
+ rec->pl_len += be32_to_cpu(fcp_rsp->ext.fr_sns_len);
}
+ /* complete FCP_RSP IU in associated PAYload record
+ * but only if there are optional parts
+ */
+ if (fcp_rsp->resp.fr_flags != 0)
+ zfcp_dbf_pl_write(
+ dbf, fcp_rsp,
+ /* at least one full PAY record
+ * but not beyond hardware response field
+ */
+ min_t(u16, max_t(u16, rec->pl_len,
+ ZFCP_DBF_PAY_MAX_REC),
+ FSF_FCP_RSP_SIZE),
+ "fcp_riu", fsf->req_id);
}
debug_event(dbf->scsi, level, rec, sizeof(*rec));
diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h
index a8165f14255..712a8484a7b 100644
--- a/drivers/s390/scsi/zfcp_dbf.h
+++ b/drivers/s390/scsi/zfcp_dbf.h
@@ -323,7 +323,11 @@ void zfcp_dbf_hba_fsf_response(struct zfcp_fsf_req *req)
{
struct fsf_qtcb *qtcb = req->qtcb;
- if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) &&
+ if (unlikely(req->status & (ZFCP_STATUS_FSFREQ_DISMISSED |
+ ZFCP_STATUS_FSFREQ_ERROR))) {
+ zfcp_dbf_hba_fsf_resp("fs_rerr", 3, req);
+
+ } else if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) &&
(qtcb->prefix.prot_status != FSF_PROT_FSF_STATUS_PRESENTED)) {
zfcp_dbf_hba_fsf_resp("fs_perr", 1, req);
diff --git a/drivers/s390/scsi/zfcp_fc.h b/drivers/s390/scsi/zfcp_fc.h
index b1d2024ed51..c2e40e10b29 100644
--- a/drivers/s390/scsi/zfcp_fc.h
+++ b/drivers/s390/scsi/zfcp_fc.h
@@ -4,7 +4,7 @@
* Fibre Channel related definitions and inline functions for the zfcp
* device driver
*
- * Copyright IBM Corp. 2009
+ * Copyright IBM Corp. 2009, 2017
*/
#ifndef ZFCP_FC_H
@@ -291,6 +291,10 @@ void zfcp_fc_eval_fcp_rsp(struct fcp_resp_with_ext *fcp_rsp,
!(rsp_flags & FCP_SNS_LEN_VAL) &&
fcp_rsp->resp.fr_status == SAM_STAT_GOOD)
set_host_byte(scsi, DID_ERROR);
+ } else if (unlikely(rsp_flags & FCP_RESID_OVER)) {
+ /* FCP_DL was not sufficient for SCSI data length */
+ if (fcp_rsp->resp.fr_status == SAM_STAT_GOOD)
+ set_host_byte(scsi, DID_ERROR);
}
}
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index ad5718401ea..d27b49194d6 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -2286,7 +2286,8 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *scsi_cmnd)
fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd;
zfcp_fc_scsi_to_fcp(fcp_cmnd, scsi_cmnd, 0);
- if (scsi_prot_sg_count(scsi_cmnd)) {
+ if ((scsi_get_prot_op(scsi_cmnd) != SCSI_PROT_NORMAL) &&
+ scsi_prot_sg_count(scsi_cmnd)) {
zfcp_qdio_set_data_div(qdio, &req->qdio_req,
scsi_prot_sg_count(scsi_cmnd));
retval = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req,
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 66c37e77ac7..8ec101a4a5e 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -294,8 +294,10 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags)
zfcp_erp_wait(adapter);
ret = fc_block_scsi_eh(scpnt);
- if (ret)
+ if (ret) {
+ zfcp_dbf_scsi_devreset("fiof", scpnt, tm_flags);
return ret;
+ }
if (!(atomic_read(&adapter->status) &
ZFCP_STATUS_COMMON_RUNNING)) {
@@ -303,8 +305,10 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags)
return SUCCESS;
}
}
- if (!fsf_req)
+ if (!fsf_req) {
+ zfcp_dbf_scsi_devreset("reqf", scpnt, tm_flags);
return FAILED;
+ }
wait_for_completion(&fsf_req->completion);
diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c
index e1c8be06de9..f94fcda1285 100644
--- a/drivers/scsi/device_handler/scsi_dh_emc.c
+++ b/drivers/scsi/device_handler/scsi_dh_emc.c
@@ -464,7 +464,7 @@ static int clariion_prep_fn(struct scsi_device *sdev, struct request *req)
static int clariion_std_inquiry(struct scsi_device *sdev,
struct clariion_dh_data *csdev)
{
- int err;
+ int err = SCSI_DH_OK;
char *sp_model;
err = send_inquiry_cmd(sdev, 0, csdev);
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index bf60c631abb..3b0f02c146d 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -299,6 +299,8 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj,
return -EINVAL;
if (start > ha->optrom_size)
return -EINVAL;
+ if (size > ha->optrom_size - start)
+ size = ha->optrom_size - start;
switch (val) {
case 0:
@@ -320,8 +322,7 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj,
return -EINVAL;
ha->optrom_region_start = start;
- ha->optrom_region_size = start + size > ha->optrom_size ?
- ha->optrom_size - start : size;
+ ha->optrom_region_size = start + size;
ha->optrom_state = QLA_SREADING;
ha->optrom_buffer = vmalloc(ha->optrom_region_size);
@@ -388,8 +389,7 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj,
}
ha->optrom_region_start = start;
- ha->optrom_region_size = start + size > ha->optrom_size ?
- ha->optrom_size - start : size;
+ ha->optrom_region_size = start + size;
ha->optrom_state = QLA_SWRITING;
ha->optrom_buffer = vmalloc(ha->optrom_region_size);
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 40fe8a77236..c11b82e7095 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -2342,10 +2342,10 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
if (mem_only) {
if (pci_enable_device_mem(pdev))
- goto probe_out;
+ return ret;
} else {
if (pci_enable_device(pdev))
- goto probe_out;
+ return ret;
}
/* This may fail but that's ok */
@@ -2355,7 +2355,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
if (!ha) {
ql_log_pci(ql_log_fatal, pdev, 0x0009,
"Unable to allocate memory for ha.\n");
- goto probe_out;
+ goto disable_device;
}
ql_dbg_pci(ql_dbg_init, pdev, 0x000a,
"Memory allocated for ha=%p.\n", ha);
@@ -2899,7 +2899,7 @@ iospace_config_failed:
kfree(ha);
ha = NULL;
-probe_out:
+disable_device:
pci_disable_device(pdev);
return ret;
}
diff --git a/drivers/soc/qcom/mpm-of.c b/drivers/soc/qcom/mpm-of.c
index 6ce72e66b73..06416595578 100644
--- a/drivers/soc/qcom/mpm-of.c
+++ b/drivers/soc/qcom/mpm-of.c
@@ -662,7 +662,7 @@ static void msm_mpm_work_fn(struct work_struct *work)
unsigned long flags;
while (1) {
bool allow;
- wait_for_completion_interruptible(&wake_wq);
+ wait_for_completion(&wake_wq);
spin_lock_irqsave(&msm_mpm_lock, flags);
allow = msm_mpm_irqs_detectable(true) &&
msm_mpm_gpio_irqs_detectable(true);
diff --git a/drivers/soc/qcom/peripheral-loader.c b/drivers/soc/qcom/peripheral-loader.c
index 12d329e37bd..a03facab903 100644
--- a/drivers/soc/qcom/peripheral-loader.c
+++ b/drivers/soc/qcom/peripheral-loader.c
@@ -771,13 +771,13 @@ out:
up_read(&pil_pm_rwsem);
if (ret) {
if (priv->region) {
+ if (desc->clear_fw_region && priv->region_start)
+ pil_clear_segment(desc);
dma_free_attrs(desc->dev, priv->region_size,
priv->region, priv->region_start,
&desc->attrs);
priv->region = NULL;
}
- if (desc->clear_fw_region && priv->region_start)
- pil_clear_segment(desc);
pil_release_mmap(desc);
}
return ret;
diff --git a/drivers/soc/qcom/qdsp6v2/voice_svc.c b/drivers/soc/qcom/qdsp6v2/voice_svc.c
index 62ccf5ee7bc..fe545897440 100644
--- a/drivers/soc/qcom/qdsp6v2/voice_svc.c
+++ b/drivers/soc/qcom/qdsp6v2/voice_svc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -42,6 +42,12 @@ struct voice_svc_prvt {
struct list_head response_queue;
wait_queue_head_t response_wait;
spinlock_t response_lock;
+ /*
+ * This mutex ensures responses are processed in sequential order and
+ * that no two threads access and free the same response at the same
+ * time.
+ */
+ struct mutex response_mutex_lock;
};
struct apr_data {
@@ -498,6 +504,7 @@ static ssize_t voice_svc_read(struct file *file, char __user *arg,
goto done;
}
+ mutex_lock(&prtd->response_mutex_lock);
spin_lock_irqsave(&prtd->response_lock, spin_flags);
if (list_empty(&prtd->response_queue)) {
@@ -511,7 +518,7 @@ static ssize_t voice_svc_read(struct file *file, char __user *arg,
pr_debug("%s: Read timeout\n", __func__);
ret = -ETIMEDOUT;
- goto done;
+ goto unlock;
} else if (ret > 0 && !list_empty(&prtd->response_queue)) {
pr_debug("%s: Interrupt recieved for response\n",
__func__);
@@ -519,7 +526,7 @@ static ssize_t voice_svc_read(struct file *file, char __user *arg,
pr_debug("%s: Interrupted by SIGNAL %d\n",
__func__, ret);
- goto done;
+ goto unlock;
}
spin_lock_irqsave(&prtd->response_lock, spin_flags);
@@ -538,7 +545,7 @@ static ssize_t voice_svc_read(struct file *file, char __user *arg,
__func__, count, size);
ret = -ENOMEM;
- goto done;
+ goto unlock;
}
if (!access_ok(VERIFY_WRITE, arg, size)) {
@@ -546,7 +553,7 @@ static ssize_t voice_svc_read(struct file *file, char __user *arg,
__func__);
ret = -EPERM;
- goto done;
+ goto unlock;
}
ret = copy_to_user(arg, &resp->resp,
@@ -556,7 +563,7 @@ static ssize_t voice_svc_read(struct file *file, char __user *arg,
pr_err("%s: copy_to_user failed %d\n", __func__, ret);
ret = -EPERM;
- goto done;
+ goto unlock;
}
spin_lock_irqsave(&prtd->response_lock, spin_flags);
@@ -570,6 +577,8 @@ static ssize_t voice_svc_read(struct file *file, char __user *arg,
ret = count;
+unlock:
+ mutex_unlock(&prtd->response_mutex_lock);
done:
return ret;
}
@@ -625,6 +634,7 @@ static int voice_svc_open(struct inode *inode, struct file *file)
INIT_LIST_HEAD(&prtd->response_queue);
init_waitqueue_head(&prtd->response_wait);
spin_lock_init(&prtd->response_lock);
+ mutex_init(&prtd->response_mutex_lock);
file->private_data = (void *)prtd;
/* Current APR implementation doesn't support session based
@@ -675,6 +685,7 @@ static int voice_svc_release(struct inode *inode, struct file *file)
pr_err("%s: Failed to dereg MVM %d\n", __func__, ret);
}
+ mutex_lock(&prtd->response_mutex_lock);
spin_lock_irqsave(&prtd->response_lock, spin_flags);
while (!list_empty(&prtd->response_queue)) {
@@ -688,6 +699,9 @@ static int voice_svc_release(struct inode *inode, struct file *file)
}
spin_unlock_irqrestore(&prtd->response_lock, spin_flags);
+ mutex_unlock(&prtd->response_mutex_lock);
+
+ mutex_destroy(&prtd->response_mutex_lock);
kfree(file->private_data);
file->private_data = NULL;
diff --git a/drivers/soc/qcom/rpm-smd.c b/drivers/soc/qcom/rpm-smd.c
index 860582f78c9..4d173d1ee80 100644
--- a/drivers/soc/qcom/rpm-smd.c
+++ b/drivers/soc/qcom/rpm-smd.c
@@ -916,7 +916,7 @@ static void msm_rpm_smd_work(struct work_struct *work)
char buf[MAX_ERR_BUFFER_SIZE] = {0};
while (1) {
- wait_for_completion_interruptible(&data_ready);
+ wait_for_completion(&data_ready);
spin_lock(&msm_rpm_data.smd_lock_read);
while (smd_is_pkt_avail(msm_rpm_data.ch_info)) {
diff --git a/drivers/soc/qcom/smp2p_spinlock_test.c b/drivers/soc/qcom/smp2p_spinlock_test.c
index 5bc1930ee7c..648c18b9e71 100644
--- a/drivers/soc/qcom/smp2p_spinlock_test.c
+++ b/drivers/soc/qcom/smp2p_spinlock_test.c
@@ -1,6 +1,6 @@
/* drivers/soc/qcom/smp2p_spinlock_test.c
*
- * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2015, 2017 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -516,7 +516,7 @@ static void smp2p_ut_remote_spinlock_ssr(struct seq_file *s)
int spinlock_owner = 0;
struct workqueue_struct *ws = NULL;
- struct rmt_spinlock_work_item work_item;
+ struct rmt_spinlock_work_item work_item = { .has_locked = false };
seq_printf(s, " Running %s Test\n",
__func__);
diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c
index 838c6dd895f..82d6da52477 100644
--- a/drivers/soc/qcom/socinfo.c
+++ b/drivers/soc/qcom/socinfo.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2015, 2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -44,6 +44,7 @@
#define SMEM_IMAGE_VERSION_OEM_OFFSET 96
#define SMEM_IMAGE_VERSION_PARTITION_APPS 10
+static DECLARE_RWSEM(current_image_rwsem);
enum {
HW_PLATFORM_UNKNOWN = 0,
HW_PLATFORM_SURF = 1,
@@ -811,7 +812,9 @@ msm_get_image_version(struct device *dev,
__func__);
return snprintf(buf, SMEM_IMAGE_VERSION_NAME_SIZE, "Unknown");
}
+ down_read(&current_image_rwsem);
string_address += current_image * SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE;
+ up_read(&current_image_rwsem);
return snprintf(buf, SMEM_IMAGE_VERSION_NAME_SIZE, "%-.75s\n",
string_address);
}
@@ -824,15 +827,20 @@ msm_set_image_version(struct device *dev,
{
char *store_address;
- if (current_image != SMEM_IMAGE_VERSION_PARTITION_APPS)
+ down_read(&current_image_rwsem);
+ if (current_image != SMEM_IMAGE_VERSION_PARTITION_APPS) {
+ up_read(&current_image_rwsem);
return count;
+ }
store_address = socinfo_get_image_version_base_address();
if (IS_ERR_OR_NULL(store_address)) {
pr_err("%s : Failed to get image version base address",
__func__);
+ up_read(&current_image_rwsem);
return count;
}
store_address += current_image * SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE;
+ up_read(&current_image_rwsem);
snprintf(store_address, SMEM_IMAGE_VERSION_NAME_SIZE, "%-.75s", buf);
return count;
}
@@ -851,7 +859,9 @@ msm_get_image_variant(struct device *dev,
return snprintf(buf, SMEM_IMAGE_VERSION_VARIANT_SIZE,
"Unknown");
}
+ down_read(&current_image_rwsem);
string_address += current_image * SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE;
+ up_read(&current_image_rwsem);
string_address += SMEM_IMAGE_VERSION_VARIANT_OFFSET;
return snprintf(buf, SMEM_IMAGE_VERSION_VARIANT_SIZE, "%-.20s\n",
string_address);
@@ -865,15 +875,20 @@ msm_set_image_variant(struct device *dev,
{
char *store_address;
- if (current_image != SMEM_IMAGE_VERSION_PARTITION_APPS)
+ down_read(&current_image_rwsem);
+ if (current_image != SMEM_IMAGE_VERSION_PARTITION_APPS) {
+ up_read(&current_image_rwsem);
return count;
+ }
store_address = socinfo_get_image_version_base_address();
if (IS_ERR_OR_NULL(store_address)) {
pr_err("%s : Failed to get image version base address",
__func__);
+ up_read(&current_image_rwsem);
return count;
}
store_address += current_image * SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE;
+ up_read(&current_image_rwsem);
store_address += SMEM_IMAGE_VERSION_VARIANT_OFFSET;
snprintf(store_address, SMEM_IMAGE_VERSION_VARIANT_SIZE, "%-.20s", buf);
return count;
@@ -892,7 +907,9 @@ msm_get_image_crm_version(struct device *dev,
__func__);
return snprintf(buf, SMEM_IMAGE_VERSION_OEM_SIZE, "Unknown");
}
+ down_read(&current_image_rwsem);
string_address += current_image * SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE;
+ up_read(&current_image_rwsem);
string_address += SMEM_IMAGE_VERSION_OEM_OFFSET;
return snprintf(buf, SMEM_IMAGE_VERSION_OEM_SIZE, "%-.32s\n",
string_address);
@@ -906,15 +923,20 @@ msm_set_image_crm_version(struct device *dev,
{
char *store_address;
- if (current_image != SMEM_IMAGE_VERSION_PARTITION_APPS)
+ down_read(&current_image_rwsem);
+ if (current_image != SMEM_IMAGE_VERSION_PARTITION_APPS) {
+ up_read(&current_image_rwsem);
return count;
+ }
store_address = socinfo_get_image_version_base_address();
if (IS_ERR_OR_NULL(store_address)) {
pr_err("%s : Failed to get image version base address",
__func__);
+ up_read(&current_image_rwsem);
return count;
}
store_address += current_image * SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE;
+ up_read(&current_image_rwsem);
store_address += SMEM_IMAGE_VERSION_OEM_OFFSET;
snprintf(store_address, SMEM_IMAGE_VERSION_OEM_SIZE, "%-.32s", buf);
return count;
@@ -925,8 +947,14 @@ msm_get_image_number(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- return snprintf(buf, PAGE_SIZE, "%d\n",
+ int ret;
+
+ down_read(&current_image_rwsem);
+ ret = snprintf(buf, PAGE_SIZE, "%d\n",
current_image);
+ up_read(&current_image_rwsem);
+ return ret;
+
}
static ssize_t
@@ -938,10 +966,12 @@ msm_select_image(struct device *dev, struct device_attribute *attr,
ret = kstrtoint(buf, 10, &digit);
if (ret)
return ret;
+ down_write(&current_image_rwsem);
if (0 <= digit && digit < SMEM_IMAGE_VERSION_BLOCKS_COUNT)
current_image = digit;
else
current_image = 0;
+ up_write(&current_image_rwsem);
return count;
}
diff --git a/drivers/soc/qcom/watchdog_v2.c b/drivers/soc/qcom/watchdog_v2.c
index 3f89b05ef01..5ada2418973 100644
--- a/drivers/soc/qcom/watchdog_v2.c
+++ b/drivers/soc/qcom/watchdog_v2.c
@@ -14,9 +14,9 @@
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/delay.h>
-#include <linux/workqueue.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
+#include <linux/kthread.h>
#include <linux/mutex.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
@@ -26,6 +26,7 @@
#include <linux/cpu.h>
#include <linux/cpu_pm.h>
#include <linux/platform_device.h>
+#include <linux/sched/rt.h>
#include <soc/qcom/scm.h>
#include <soc/qcom/memory_dump.h>
#include <soc/qcom/watchdog.h>
@@ -50,7 +51,6 @@
#define SCM_SET_REGSAVE_CMD 0x2
#define SCM_SVC_SEC_WDOG_DIS 0x7
-static struct workqueue_struct *wdog_wq;
static struct msm_watchdog_data *wdog_data;
static struct msm_watchdog_data *g_wdog_dd;
@@ -74,12 +74,13 @@ struct msm_watchdog_data {
void *scm_regsave;
cpumask_t alive_mask;
struct mutex disable_lock;
- struct work_struct init_dogwork_struct;
- struct delayed_work dogwork_struct;
bool irq_ppi;
struct msm_watchdog_data __percpu **wdog_cpu_dd;
struct notifier_block panic_blk;
bool enabled;
+ struct task_struct *watchdog_task;
+ struct timer_list pet_timer;
+ struct completion pet_complete;
phys_addr_t cpu_ctx_addr;
size_t cpu_ctx_size_percpu;
};
@@ -108,9 +109,6 @@ module_param(WDT_HZ, long, 0);
static int ipi_opt_en;
module_param(ipi_opt_en, int, 0);
-static void pet_watchdog_work(struct work_struct *work);
-static void init_watchdog_work(struct work_struct *work);
-
static void dump_cpu_alive_mask(struct msm_watchdog_data *wdog_dd)
{
static char alive_mask_buf[MASK_SIZE];
@@ -192,7 +190,7 @@ static void wdog_disable(struct msm_watchdog_data *wdog_dd)
smp_mb();
atomic_notifier_chain_unregister(&panic_notifier_list,
&wdog_dd->panic_blk);
- cancel_delayed_work_sync(&wdog_dd->dogwork_struct);
+ del_timer_sync(&wdog_dd->pet_timer);
/* may be suspended after the first write above */
__raw_writel(0, wdog_dd->base + WDT0_EN);
mb();
@@ -200,20 +198,6 @@ static void wdog_disable(struct msm_watchdog_data *wdog_dd)
pr_info("MSM Apps Watchdog deactivated.\n");
}
-struct wdog_disable_work_data {
- struct work_struct work;
- struct completion complete;
- struct msm_watchdog_data *wdog_dd;
-};
-
-static void wdog_disable_work(struct work_struct *work)
-{
- struct wdog_disable_work_data *work_data =
- container_of(work, struct wdog_disable_work_data, work);
- wdog_disable(work_data->wdog_dd);
- complete(&work_data->complete);
-}
-
static ssize_t wdog_disable_get(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -232,7 +216,6 @@ static ssize_t wdog_disable_set(struct device *dev,
{
int ret;
u8 disable;
- struct wdog_disable_work_data work_data;
struct msm_watchdog_data *wdog_dd = dev_get_drvdata(dev);
ret = kstrtou8(buf, 10, &disable);
@@ -264,11 +247,7 @@ static ssize_t wdog_disable_set(struct device *dev,
mutex_unlock(&wdog_dd->disable_lock);
return -EIO;
}
- work_data.wdog_dd = wdog_dd;
- init_completion(&work_data.complete);
- INIT_WORK_ONSTACK(&work_data.work, wdog_disable_work);
- queue_work(wdog_wq, &work_data.work);
- wait_for_completion(&work_data.complete);
+ wdog_disable(wdog_dd);
mutex_unlock(&wdog_dd->disable_lock);
} else {
pr_err("invalid operation, only disable = 1 supported\n");
@@ -334,24 +313,37 @@ static void ping_other_cpus(struct msm_watchdog_data *wdog_dd)
}
}
-static void pet_watchdog_work(struct work_struct *work)
+static void pet_task_wakeup(unsigned long data)
{
- unsigned long delay_time;
- struct delayed_work *delayed_work = to_delayed_work(work);
- struct msm_watchdog_data *wdog_dd = container_of(delayed_work,
- struct msm_watchdog_data,
- dogwork_struct);
- delay_time = msecs_to_jiffies(wdog_dd->pet_time);
- if (enable) {
- if (wdog_dd->do_ipi_ping)
- ping_other_cpus(wdog_dd);
- pet_watchdog(wdog_dd);
+ struct msm_watchdog_data *wdog_dd =
+ (struct msm_watchdog_data *)data;
+ complete(&wdog_dd->pet_complete);
+}
+
+static __ref int watchdog_kthread(void *arg)
+{
+ struct msm_watchdog_data *wdog_dd =
+ (struct msm_watchdog_data *)arg;
+ unsigned long delay_time = 0;
+ struct sched_param param = {.sched_priority = MAX_RT_PRIO-1};
+
+ sched_setscheduler(current, SCHED_FIFO, &param);
+ while (!kthread_should_stop()) {
+ while (wait_for_completion_interruptible(
+ &wdog_dd->pet_complete) != 0)
+ ;
+ INIT_COMPLETION(wdog_dd->pet_complete);
+ if (enable) {
+ delay_time = msecs_to_jiffies(wdog_dd->pet_time);
+ if (wdog_dd->do_ipi_ping)
+ ping_other_cpus(wdog_dd);
+ pet_watchdog(wdog_dd);
+ }
+ /* Check again before scheduling *
+ * Could have been changed on other cpu */
+ mod_timer(&wdog_dd->pet_timer, jiffies + delay_time);
}
- /* Check again before scheduling *
- * Could have been changed on other cpu */
- if (enable)
- queue_delayed_work(wdog_wq,
- &wdog_dd->dogwork_struct, delay_time);
+ return 0;
}
static int wdog_cpu_pm_notify(struct notifier_block *self,
@@ -380,7 +372,6 @@ static struct notifier_block wdog_cpu_pm_nb = {
static int msm_watchdog_remove(struct platform_device *pdev)
{
- struct wdog_disable_work_data work_data;
struct msm_watchdog_data *wdog_dd =
(struct msm_watchdog_data *)platform_get_drvdata(pdev);
@@ -389,18 +380,15 @@ static int msm_watchdog_remove(struct platform_device *pdev)
mutex_lock(&wdog_dd->disable_lock);
if (enable) {
- work_data.wdog_dd = wdog_dd;
- init_completion(&work_data.complete);
- INIT_WORK_ONSTACK(&work_data.work, wdog_disable_work);
- queue_work(wdog_wq, &work_data.work);
- wait_for_completion(&work_data.complete);
+ wdog_disable(wdog_dd);
}
mutex_unlock(&wdog_dd->disable_lock);
device_remove_file(wdog_dd->dev, &dev_attr_disable);
if (wdog_dd->irq_ppi)
free_percpu(wdog_dd->wdog_cpu_dd);
printk(KERN_INFO "MSM Watchdog Exit - Deactivated\n");
- destroy_workqueue(wdog_wq);
+ del_timer_sync(&wdog_dd->pet_timer);
+ kthread_stop(wdog_dd->watchdog_task);
kfree(wdog_dd);
return 0;
}
@@ -560,11 +548,8 @@ out0:
}
-static void init_watchdog_work(struct work_struct *work)
+static void init_watchdog_data(struct msm_watchdog_data *wdog_dd)
{
- struct msm_watchdog_data *wdog_dd = container_of(work,
- struct msm_watchdog_data,
- init_dogwork_struct);
unsigned long delay_time;
uint32_t val;
int error;
@@ -614,8 +599,14 @@ static void init_watchdog_work(struct work_struct *work)
atomic_notifier_chain_register(&panic_notifier_list,
&wdog_dd->panic_blk);
mutex_init(&wdog_dd->disable_lock);
- queue_delayed_work(wdog_wq, &wdog_dd->dogwork_struct,
- delay_time);
+ init_completion(&wdog_dd->pet_complete);
+ wake_up_process(wdog_dd->watchdog_task);
+ init_timer(&wdog_dd->pet_timer);
+ wdog_dd->pet_timer.data = (unsigned long)wdog_dd;
+ wdog_dd->pet_timer.function = pet_task_wakeup;
+ wdog_dd->pet_timer.expires = jiffies + delay_time;
+ add_timer(&wdog_dd->pet_timer);
+
val = BIT(EN);
if (wdog_dd->wakeup_irq_enable)
val |= BIT(UNMASKED_INT_EN);
@@ -725,12 +716,6 @@ static int msm_watchdog_probe(struct platform_device *pdev)
int ret;
struct msm_watchdog_data *wdog_dd;
- wdog_wq = alloc_workqueue("wdog", WQ_HIGHPRI, 0);
- if (!wdog_wq) {
- pr_err("Failed to allocate watchdog workqueue\n");
- return -EIO;
- }
-
if (!pdev->dev.of_node || !enable)
return -ENODEV;
wdog_dd = kzalloc(sizeof(struct msm_watchdog_data), GFP_KERNEL);
@@ -746,13 +731,16 @@ static int msm_watchdog_probe(struct platform_device *pdev)
msm_wdog_get_cpu_ctx(pdev, &wdog_dd->cpu_ctx_addr,
&wdog_dd->cpu_ctx_size_percpu);
cpumask_clear(&wdog_dd->alive_mask);
- INIT_WORK(&wdog_dd->init_dogwork_struct, init_watchdog_work);
- INIT_DELAYED_WORK(&wdog_dd->dogwork_struct, pet_watchdog_work);
+ wdog_dd->watchdog_task = kthread_create(watchdog_kthread, wdog_dd,
+ "msm_watchdog");
+ if (IS_ERR(wdog_dd->watchdog_task)) {
+ ret = PTR_ERR(wdog_dd->watchdog_task);
+ goto err;
+ }
+ init_watchdog_data(wdog_dd);
g_wdog_dd = wdog_dd;
- queue_work(wdog_wq, &wdog_dd->init_dogwork_struct);
return 0;
err:
- destroy_workqueue(wdog_wq);
kzfree(wdog_dd);
return ret;
}
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index 1b64f1aa93b..625f0003ca9 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -1,9 +1,9 @@
/*
- * drivers/gpu/ion/ion.c
+ * drivers/staging/android/ion/ion.c
*
* Copyright (C) 2011 Google, Inc.
- * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -696,7 +696,7 @@ static void user_ion_free_nolock(struct ion_client *client,
WARN(1, "%s: invalid handle passed to free.\n", __func__);
return;
}
- if (!handle->user_ref_count > 0) {
+ if (handle->user_ref_count == 0) {
WARN(1, "%s: User does not have access!\n", __func__);
return;
}
@@ -2010,10 +2010,11 @@ void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap)
up_write(&dev->lock);
}
-int ion_walk_heaps(struct ion_client *client, int heap_id, void *data,
+int ion_walk_heaps(struct ion_client *client, int heap_id,
+ enum ion_heap_type type, void *data,
int (*f)(struct ion_heap *heap, void *data))
{
- int ret_val = -EINVAL;
+ int ret_val = 0;
struct ion_heap *heap;
struct ion_device *dev = client->dev;
/*
@@ -2022,7 +2023,8 @@ int ion_walk_heaps(struct ion_client *client, int heap_id, void *data,
*/
down_write(&dev->lock);
plist_for_each_entry(heap, &dev->heaps, node) {
- if (ION_HEAP(heap->id) != heap_id)
+ if (ION_HEAP(heap->id) != heap_id ||
+ type != heap->type)
continue;
ret_val = f(heap, data);
break;
diff --git a/drivers/staging/android/ion/ion_carveout_heap.c b/drivers/staging/android/ion/ion_carveout_heap.c
index 343bbd81dbd..231936c63ab 100644
--- a/drivers/staging/android/ion/ion_carveout_heap.c
+++ b/drivers/staging/android/ion/ion_carveout_heap.c
@@ -90,6 +90,9 @@ static int ion_carveout_heap_allocate(struct ion_heap *heap,
unsigned long size, unsigned long align,
unsigned long flags)
{
+ if (align > PAGE_SIZE)
+ return -EINVAL;
+
buffer->priv_phys = ion_carveout_allocate(heap, size, align);
return buffer->priv_phys == ION_CARVEOUT_ALLOCATE_FAIL ? -ENOMEM : 0;
}
diff --git a/drivers/staging/android/ion/ion_priv.h b/drivers/staging/android/ion/ion_priv.h
index 0f0e2879560..371b8a7ad5d 100644
--- a/drivers/staging/android/ion/ion_priv.h
+++ b/drivers/staging/android/ion/ion_priv.h
@@ -1,8 +1,8 @@
/*
- * drivers/gpu/ion/ion_priv.h
+ * drivers/staging/android/ion/ion_priv.h
*
* Copyright (C) 2011 Google, Inc.
- * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -441,7 +441,8 @@ int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask,
void ion_pages_sync_for_device(struct device *dev, struct page *page,
size_t size, enum dma_data_direction dir);
-int ion_walk_heaps(struct ion_client *client, int heap_id, void *data,
+int ion_walk_heaps(struct ion_client *client, int heap_id,
+ enum ion_heap_type type, void *data,
int (*f)(struct ion_heap *heap, void *data));
struct ion_handle *ion_handle_get_by_id(struct ion_client *client,
diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c
index af7802d28bf..7a4a8020d12 100644
--- a/drivers/staging/android/ion/ion_system_heap.c
+++ b/drivers/staging/android/ion/ion_system_heap.c
@@ -124,6 +124,10 @@ static struct page_info *alloc_largest_available(struct ion_system_heap *heap,
if (!info)
return NULL;
+ info = kmalloc(sizeof(struct page_info), GFP_KERNEL);
+ if (!info)
+ return NULL;
+
for (i = 0; i < num_orders; i++) {
if (size < order_to_size(orders[i]))
continue;
diff --git a/drivers/staging/android/ion/msm/msm_ion.c b/drivers/staging/android/ion/msm/msm_ion.c
index c79bcfc6359..fd67158512a 100644
--- a/drivers/staging/android/ion/msm/msm_ion.c
+++ b/drivers/staging/android/ion/msm/msm_ion.c
@@ -756,16 +756,28 @@ long msm_ion_custom_ioctl(struct ion_client *client,
}
case ION_IOC_PREFETCH:
{
- ion_walk_heaps(client, data.prefetch_data.heap_id,
+ int ret;
+
+ ret = ion_walk_heaps(client, data.prefetch_data.heap_id,
+ ION_HEAP_TYPE_SECURE_DMA,
(void *)data.prefetch_data.len,
ion_secure_cma_prefetch);
+
+ if (ret)
+ return ret;
break;
}
case ION_IOC_DRAIN:
{
- ion_walk_heaps(client, data.prefetch_data.heap_id,
+ int ret;
+
+ ret = ion_walk_heaps(client, data.prefetch_data.heap_id,
+ ION_HEAP_TYPE_SECURE_DMA,
(void *)data.prefetch_data.len,
ion_secure_cma_drain_pool);
+
+ if (ret)
+ return ret;
break;
}
diff --git a/drivers/staging/android/oneshot_sync.c b/drivers/staging/android/oneshot_sync.c
index 317720ade3a..6a56ee9d6b0 100644
--- a/drivers/staging/android/oneshot_sync.c
+++ b/drivers/staging/android/oneshot_sync.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014,2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index 0ae406a4750..2aba2f75fb8 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -2557,15 +2557,13 @@ static int __init comedi_init(void)
comedi_class->dev_attrs = comedi_dev_attrs;
- /* XXX requires /proc interface */
- comedi_proc_init();
-
/* create devices files for legacy/manual use */
for (i = 0; i < comedi_num_legacy_minors; i++) {
struct comedi_device *dev;
dev = comedi_alloc_board_minor(NULL);
if (IS_ERR(dev)) {
comedi_cleanup_board_minors();
+ class_destroy(comedi_class);
cdev_del(&comedi_cdev);
unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
COMEDI_NUM_MINORS);
@@ -2576,6 +2574,9 @@ static int __init comedi_init(void)
}
}
+ /* XXX requires /proc interface */
+ comedi_proc_init();
+
return 0;
}
module_init(comedi_init);
diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index 0d3356d4b7d..3c0b16fe172 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -477,7 +477,7 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev,
long m)
{
struct ad2s1210_state *st = iio_priv(indio_dev);
- bool negative;
+ u16 negative;
int ret = 0;
u16 pos;
s16 vel;
diff --git a/drivers/staging/prima/Android.mk b/drivers/staging/prima/Android.mk
index 37dc852a7f8..de0c7354aea 100644
--- a/drivers/staging/prima/Android.mk
+++ b/drivers/staging/prima/Android.mk
@@ -10,7 +10,7 @@ WLAN_SELECT := CONFIG_PRIMA_WLAN=m
endif
# Build/Package options for 8916, 8974, 8226, 8610, 8909, 8952, 8937, 8953 targets
-ifneq (,$(filter msm8916 msm8974 msm8226 msm8610 msm8909 msm8952 msm8937 msm8953 msm8953,$(TARGET_BOARD_PLATFORM)))
+ifneq (,$(filter msm8916 msm8974 msm8226 msm8610 msm8909 msm8952 msm8937 msm8953 titanium,$(TARGET_BOARD_PLATFORM)))
WLAN_CHIPSET := pronto
WLAN_SELECT := CONFIG_PRONTO_WLAN=m
endif
@@ -20,8 +20,22 @@ ifneq ($(WLAN_CHIPSET),)
LOCAL_PATH := $(call my-dir)
-# This makefile is only for DLKM
+ifeq ($(TARGET_SUPPORTS_WEARABLES),true)
+ifneq ($(findstring device,$(LOCAL_PATH)),)
+ WLAN_DLKM := 1
+else
+ WLAN_DLKM := 0
+endif # findstring device
+else
ifneq ($(findstring vendor,$(LOCAL_PATH)),)
+ WLAN_DLKM := 1
+else
+ WLAN_DLKM := 0
+endif # findstring vendor
+endif # TARGET_SUPPORTS_WEARABLES
+
+# This makefile is only for DLKM
+ifeq ($(WLAN_DLKM),1)
# Determine if we are Proprietary or Open Source
ifneq ($(findstring opensource,$(LOCAL_PATH)),)
@@ -33,13 +47,21 @@ endif
ifeq ($(WLAN_PROPRIETARY),1)
WLAN_BLD_DIR := vendor/qcom/proprietary/wlan
else
+ifneq ($(TARGET_SUPPORTS_WEARABLES),true)
WLAN_BLD_DIR := vendor/qcom/opensource/wlan
+else
+ WLAN_BLD_DIR := device/qcom/msm8909w/opensource/wlan
+endif
endif
# DLKM_DIR was moved for JELLY_BEAN (PLATFORM_SDK 16)
ifeq (1,$(filter 1,$(shell echo "$$(( $(PLATFORM_SDK_VERSION) >= 16 ))" )))
+ifneq ($(TARGET_SUPPORTS_WEARABLES),true)
DLKM_DIR := $(TOP)/device/qcom/common/dlkm
else
+ DLKM_DIR := $(BOARD_DLKM_DIR)
+endif
+else
DLKM_DIR := build/dlkm
endif
@@ -111,15 +133,24 @@ LOCAL_MODULE := $(WLAN_CHIPSET)_wlan.ko
LOCAL_MODULE_KBUILD_NAME := wlan.ko
LOCAL_MODULE_TAGS := debug
LOCAL_MODULE_DEBUG_ENABLE := true
+ifeq ($(PRODUCT_VENDOR_MOVE_ENABLED), true)
+LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/lib/modules/$(WLAN_CHIPSET)
+else
LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/modules/$(WLAN_CHIPSET)
+endif # PRODUCT_VENDOR_MOVE_ENABLED
include $(DLKM_DIR)/AndroidKernelModule.mk
###########################################################
#Create symbolic link
+ifeq ($(PRODUCT_VENDOR_MOVE_ENABLED), true)
+$(shell mkdir -p $(TARGET_OUT_VENDOR)/lib/modules; \
+ ln -sf /$(TARGET_COPY_OUT_VENDOR)/lib/modules/$(WLAN_CHIPSET)/$(WLAN_CHIPSET)_wlan.ko \
+ $(TARGET_OUT_VENDOR)/lib/modules/wlan.ko)
+else
$(shell mkdir -p $(TARGET_OUT)/lib/modules; \
ln -sf /system/lib/modules/$(WLAN_CHIPSET)/$(WLAN_CHIPSET)_wlan.ko \
$(TARGET_OUT)/lib/modules/wlan.ko)
-
+endif # PRODUCT_VENDOR_MOVE_ENABLED
endif # DLKM check
endif # supported target check
diff --git a/drivers/staging/prima/CORE/HDD/inc/qc_sap_ioctl.h b/drivers/staging/prima/CORE/HDD/inc/qc_sap_ioctl.h
index 2bc3b6aba15..764384e14f8 100644
--- a/drivers/staging/prima/CORE/HDD/inc/qc_sap_ioctl.h
+++ b/drivers/staging/prima/CORE/HDD/inc/qc_sap_ioctl.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -142,6 +142,10 @@ typedef struct
#define QCSAP_IOCTL_GETPARAM (SIOCIWFIRSTPRIV+1)
#define QCSAP_IOCTL_COMMIT (SIOCIWFIRSTPRIV+2)
+#define QCSAP_IOCTL_SET_CHAR_GET_NONE (SIOCIWFIRSTPRIV + 3)
+#define WE_WOWL_ADD_PTRN 1
+#define WE_WOWL_DEL_PTRN 2
+
#define QCSAP_IOCTL_GET_STAWPAIE (SIOCIWFIRSTPRIV+4)
#define QCSAP_IOCTL_STOPBSS (SIOCIWFIRSTPRIV+6)
@@ -173,6 +177,9 @@ typedef struct
#define QCSAP_IOCTL_SET_TRAFFIC_MONITOR (SIOCIWFIRSTPRIV+24)
#define QCSAP_IOCTL_AP_STATS (SIOCIWFIRSTPRIV+25) // get routines should be odd numbered
+#define QCSAP_IOCTL_PRIV_SET_NONE_GET_THREE_INT (SIOCIWFIRSTPRIV+27)
+#define QCSAP_IOCTL_GET_TSF 1
+
#define MAX_VAR_ARGS 7
#define QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED (SIOCIWFIRSTPRIV + 31)
@@ -186,7 +193,9 @@ enum {
QCSAP_PARAM_SET_MC_RATE = 10,
QCSAP_PARAM_SET_AUTO_CHANNEL = 11,
QCSAP_PARAM_GET_FRAME_LOGS = 12,
- QCSAP_PARAM_SET_PROXIMITY = 13
+ QCSAP_PARAM_SET_PROXIMITY = 13,
+ QCSAP_PARAM_SET_WOWL = 14,
+ QCSAP_PARAM_CAP_TSF = 15
};
int iw_softap_get_channel_list(struct net_device *dev,
diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_assoc.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_assoc.h
index 81947302e55..01620346d23 100644
--- a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_assoc.h
+++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_assoc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -31,6 +31,8 @@
#if !defined( HDD_CONNECTION_H__ )
#define HDD_CONNECTION_H__
#include <wlan_hdd_mib.h>
+#include <net/cfg80211.h>
+#include <linux/ieee80211.h>
#define HDD_MAX_NUM_IBSS_STA ( 32 )
#ifdef FEATURE_WLAN_TDLS
#define HDD_MAX_NUM_TDLS_STA ( 8 )
@@ -47,6 +49,57 @@
/* Timeout in ms for peer info request commpletion */
#define IBSS_PEER_INFO_REQ_TIMOEUT 1000
#endif
+
+/**
+ * struct hdd_conn_flag - connection flags
+ * @ht_present: ht element present or not
+ * @vht_present: vht element present or not
+ * @hs20_present: hs20 element present or not
+ */
+struct hdd_conn_flag {
+ uint8_t ht_present:1;
+ uint8_t vht_present:1;
+ uint8_t hs20_present:1;
+ uint8_t ht_op_present:1;
+ uint8_t vht_op_present:1;
+ uint8_t reserved:3;
+};
+
+/*defines for tx_BF_cap_info */
+#define TX_BF_CAP_INFO_TX_BF 0x00000001
+#define TX_BF_CAP_INFO_RX_STAG_RED_SOUNDING 0x00000002
+#define TX_BF_CAP_INFO_TX_STAG_RED_SOUNDING 0x00000004
+#define TX_BF_CAP_INFO_RX_ZFL 0x00000008
+#define TX_BF_CAP_INFO_TX_ZFL 0x00000010
+#define TX_BF_CAP_INFO_IMP_TX_BF 0x00000020
+#define TX_BF_CAP_INFO_CALIBRATION 0x000000c0
+#define TX_BF_CAP_INFO_CALIBRATION_SHIFT 6
+#define TX_BF_CAP_INFO_EXP_CSIT_BF 0x00000100
+#define TX_BF_CAP_INFO_EXP_UNCOMP_STEER_MAT 0x00000200
+#define TX_BF_CAP_INFO_EXP_BF_CSI_FB 0x00001c00
+#define TX_BF_CAP_INFO_EXP_BF_CSI_FB_SHIFT 10
+#define TX_BF_CAP_INFO_EXP_UNCMP_STEER_MAT 0x0000e000
+#define TX_BF_CAP_INFO_EXP_UNCMP_STEER_MAT_SHIFT 13
+#define TX_BF_CAP_INFO_EXP_CMP_STEER_MAT_FB 0x00070000
+#define TX_BF_CAP_INFO_EXP_CMP_STEER_MAT_FB_SHIFT 16
+#define TX_BF_CAP_INFO_CSI_NUM_BF_ANT 0x00180000
+#define TX_BF_CAP_INFO_CSI_NUM_BF_ANT_SHIFT 18
+#define TX_BF_CAP_INFO_UNCOMP_STEER_MAT_BF_ANT 0x00600000
+#define TX_BF_CAP_INFO_UNCOMP_STEER_MAT_BF_ANT_SHIFT 20
+#define TX_BF_CAP_INFO_COMP_STEER_MAT_BF_ANT 0x01800000
+#define TX_BF_CAP_INFO_COMP_STEER_MAT_BF_ANT_SHIFT 22
+#define TX_BF_CAP_INFO_RSVD 0xfe000000
+
+/* defines for antenna selection info */
+#define ANTENNA_SEL_INFO 0x01
+#define ANTENNA_SEL_INFO_EXP_CSI_FB_TX 0x02
+#define ANTENNA_SEL_INFO_ANT_ID_FB_TX 0x04
+#define ANTENNA_SEL_INFO_EXP_CSI_FB 0x08
+#define ANTENNA_SEL_INFO_ANT_ID_FB 0x10
+#define ANTENNA_SEL_INFO_RX_AS 0x20
+#define ANTENNA_SEL_INFO_TX_SOUNDING_PPDU 0x40
+#define ANTENNA_SEL_INFO_RSVD 0x80
+
typedef enum
{
/** Not associated in Infra or participating in an IBSS / Ad-hoc network.*/
@@ -112,7 +165,42 @@ typedef struct connection_info_s
tANI_U32 dot11Mode;
uint32_t rate_flags;
-
+
+ /** channel frequency */
+ uint32_t freq;
+
+ /** txrate structure holds nss & datarate info */
+ struct rate_info txrate;
+
+ /** noise information */
+ int8_t noise;
+
+ /** ht capabilities info */
+ struct ieee80211_ht_cap ht_caps;
+
+ /** vht capabilities info */
+ struct ieee80211_vht_cap vht_caps;
+
+ /** passpoint/hs20 info */
+ tDot11fIEhs20vendor_ie hs20vendor_ie;
+
+ /** conn info params is present or not */
+ struct hdd_conn_flag conn_flag;
+
+ /** ht operation info */
+ struct ieee80211_ht_operation ht_operation;
+
+ /** ht operation info */
+ struct ieee80211_vht_operation vht_operation;
+
+ /** roaming counter */
+ uint32_t roam_count;
+
+ /** rssi info */
+ int8_t signal;
+
+ /** assoc fail reason */
+ int32_t assoc_status_code;
}connection_info_t;
/*Forward declaration of Adapter*/
typedef struct hdd_adapter_s hdd_adapter_t;
@@ -135,6 +223,9 @@ v_BOOL_t hdd_connGetConnectedBssType( hdd_station_ctx_t *pHddCtx,
int hdd_SetGENIEToCsr( hdd_adapter_t *pAdapter, eCsrAuthType *RSNAuthType );
int hdd_set_csr_auth_type( hdd_adapter_t *pAdapter, eCsrAuthType RSNAuthType );
+
+void hdd_assoc_registerFwdEapolCB(void *pContext);
+
VOS_STATUS hdd_roamRegisterTDLSSTA( hdd_adapter_t *pAdapter,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
const tANI_U8 *peerMac,
diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_cfg.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_cfg.h
index 45921187e88..d08c9fcc97b 100644
--- a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_cfg.h
+++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_cfg.h
@@ -47,9 +47,20 @@
#include <vos_types.h>
#include <csrApi.h>
+#ifdef DHCP_SERVER_OFFLOAD
+#define IPADDR_NUM_ENTRIES (4)
+#define IPADDR_STRING_LENGTH (16)
+#define DHCP_START_POOL_ADDRESS 100
+#endif /* DHCP_SERVER_OFFLOAD */
+
//Number of items that can be configured
#define MAX_CFG_INI_ITEMS 512
+#ifdef SAP_AUTH_OFFLOAD
+/* 802.11 pre-share key length */
+#define WLAN_PSK_STRING_LENGTH (64)
+#endif /* SAP_AUTH_OFFLOAD */
+
// Defines for all of the things we read from the configuration (registry).
#define CFG_RTS_THRESHOLD_NAME "RTSThreshold"
@@ -355,6 +366,11 @@ typedef enum
#define CFG_CHANNEL_BONDING_MODE_MAX WNI_CFG_CHANNEL_BONDING_MODE_STAMAX
#define CFG_CHANNEL_BONDING_MODE_DEFAULT WNI_CFG_CHANNEL_BONDING_MODE_STADEF
+#define CFG_OVERRIDE_HT40_20_24GHZ_NAME "override_ht20_40_24g"
+#define CFG_OVERRIDE_HT40_20_24GHZ_MIN 0
+#define CFG_OVERRIDE_HT40_20_24GHZ_MAX 1
+#define CFG_OVERRIDE_HT40_20_24GHZ_DEFAULT 0
+
#define CFG_CHANNEL_BONDING_MODE_5GHZ_NAME "gChannelBondingMode5GHz"
#define CFG_CHANNEL_BONDING_MODE_MIN WNI_CFG_CHANNEL_BONDING_MODE_STAMIN
#define CFG_CHANNEL_BONDING_MODE_MAX WNI_CFG_CHANNEL_BONDING_MODE_STAMAX
@@ -1433,6 +1449,16 @@ typedef enum
#define CFG_NEIGHBOR_INITIAL_FORCED_ROAM_TO_5GH_ENABLE_MAX (1)
#define CFG_NEIGHBOR_INITIAL_FORCED_ROAM_TO_5GH_ENABLE_DEFAULT (0)
+/*
+ * gWeakZoneRssiThresholdForRoam is the minimum threshold value to get
+ * candidate list from firmware, firmware filters the received candidate with
+ * this param before sending candidate list to host.
+ */
+#define CFG_NEIGHBOR_WEAK_ZONE_RSSI_THRESHOLD_FOR_ROAM_NAME "gWeakZoneRssiThresholdForRoam"
+#define CFG_NEIGHBOR_WEAK_ZONE_RSSI_THRESHOLD_FOR_ROAM_MIN (40)
+#define CFG_NEIGHBOR_WEAK_ZONE_RSSI_THRESHOLD_FOR_ROAM_MAX (100)
+#define CFG_NEIGHBOR_WEAK_ZONE_RSSI_THRESHOLD_FOR_ROAM_DEFAULT (80)
+
#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */
#define CFG_QOS_WMM_BURST_SIZE_DEFN_NAME "burstSizeDefinition"
@@ -1545,6 +1571,25 @@ typedef enum
#define CFG_ENABLE_DFS_PNO_CHNL_SCAN_MAX ( 1 )
#define CFG_ENABLE_DFS_PNO_CHNL_SCAN_DEFAULT ( 1 )
+/*
+ * gStaAuthRetriesForCode17
+ * It is for an IOT issue.
+ * When DUT receives MAX_ASSOC_STA_REACHED_STATUS as
+ * response for Auth frame this ini decides how many
+ * times DUT has to retry.
+ *
+ * This is mainly for an AP where it wants to force
+ * the Station to connect to its 5G profile session
+ * (Dual band AP) by rejecting the Auth on 2.4G band.
+ * But if a station is only 2.4G capable it can try
+ * 3 times where third time AP will allow the
+ * station to connect to this AP.
+ */
+#define CFG_STA_AUTH_RETRIES_FOR_CODE17_NAME "gStaAuthRetriesForCode17"
+#define CFG_STA_AUTH_RETRIES_FOR_CODE17_MIN ( 0 )
+#define CFG_STA_AUTH_RETRIES_FOR_CODE17_MAX ( 5 )
+#define CFG_STA_AUTH_RETRIES_FOR_CODE17_DEFAULT ( 0 )
+
typedef enum
{
eHDD_LINK_SPEED_REPORT_ACTUAL = 0,
@@ -1656,6 +1701,29 @@ typedef enum
#define CFG_ENABLE_TCP_DELACK_MAX (1)
#define CFG_ENABLE_TCP_DELACK_DEFAULT (1)
+#ifdef SAP_AUTH_OFFLOAD
+/* Enable/Disable SAP Authentication offload
+ * Default: enable
+ */
+#define CFG_ENABLE_SAP_AUTH_OFL_NAME "gEnableSAPAuthOffload"
+#define CFG_ENABLE_SAP_AUTH_OFL_MIN ( 0 )
+#define CFG_ENABLE_SAP_AUTH_OFL_MAX ( 1 )
+#define CFG_ENABLE_SAP_AUTH_OFL_DEFAULT ( 1 )
+
+/* SAP Authentication offload Security Type
+ * 0: None Security
+ * 1: WPA2-PSK CCMP
+ */
+#define CFG_SAP_AUTH_OFL_SECURITY_TYPE_NAME "gSAPAuthOffloadSec"
+#define CFG_SAP_AUTH_OFL_SECURITY_TYPE_MIN ( 0 )
+#define CFG_SAP_AUTH_OFL_SECURITY_TYPE_MAX ( 1 )
+#define CFG_SAP_AUTH_OFL_SECURITY_TYPE_DEFAULT ( 0 )
+
+/* SAP Authentication offload Security Key */
+#define CFG_SAP_AUTH_OFL_KEY_NAME "gSAPAuthOffloadKey"
+#define CFG_SAP_AUTH_OFL_KEY_DEFAULT ""
+#endif /* SAP_AUTH_OFFLOAD */
+
/* In cfg.dat 1=1MBPS, 2=2MBPS, 3=5_5MBPS, 4=11MBPS, 5=6MBPS, 6=9MBPS,
* 7=12MBPS, 8=18MBPS, 9=24MBPS. But 6=9MBPS and 8=18MBPS are not basic
* 11g rates and should not be set by gDefaultRateIndex24Ghz. So instead
@@ -2374,6 +2442,13 @@ This feature requires the dependent cfg.ini "gRoamPrefer5GHz" set to 1 */
#define CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN_DEFAULT ( 120000 )
#define CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN_MIN ( 0 )
#define CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN_MAX ( 250000 )
+
+
+#define CFG_BTC_DISABLE_WLAN_LINK_CRITICAL "gBtcDisableWlanLinkCritical"
+#define CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_DEFAULT ( 0 )
+#define CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_MIN ( 0 )
+#define CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_MAX ( 1 )
+
/*
* Connection related log Enable/Disable.
* 0x1 - Enable mgmt pkt logs (no probe req/rsp).
@@ -2404,7 +2479,7 @@ This feature requires the dependent cfg.ini "gRoamPrefer5GHz" set to 1 */
#define CFG_RA_RATE_LIMIT_INTERVAL_NAME "gRARateLimitInterval"
#define CFG_RA_RATE_LIMIT_INTERVAL_DEFAULT (60)
#define CFG_RA_RATE_LIMIT_INTERVAL_MIN (0)
-#define CFG_RA_RATE_LIMIT_INTERVAL_MAX (60)
+#define CFG_RA_RATE_LIMIT_INTERVAL_MAX (3600)
#define CFG_ROAMING_DFS_CHANNEL_NAME "gAllowDFSChannelRoam"
#define CFG_ROAMING_DFS_CHANNEL_MIN (0)
@@ -2708,6 +2783,102 @@ This feature requires the dependent cfg.ini "gRoamPrefer5GHz" set to 1 */
#define CFG_DISABLE_BAR_WAKEUP_HOST_MAX 1
#define CFG_DISABLE_BAR_WAKEUP_HOST_DEFAULT 0
+#ifdef DHCP_SERVER_OFFLOAD
+/*
+ * Enable/Disable DHCP Server Offload
+ * Default: Disable
+ */
+#define CFG_DHCP_SERVER_OFFLOAD_SUPPORT_NAME "gDHCPServerOffloadEnable"
+#define CFG_DHCP_SERVER_OFFLOAD_SUPPORT_MIN ( 0 )
+#define CFG_DHCP_SERVER_OFFLOAD_SUPPORT_MAX ( 1 )
+#define CFG_DHCP_SERVER_OFFLOAD_SUPPORT_DEFAULT ( 1 )
+
+/* Max number of DHCP clients to be supported */
+#define CFG_DHCP_SERVER_OFFLOAD_NUM_CLIENT_NAME "gDHCPMaxNumClients"
+#define CFG_DHCP_SERVER_OFFLOAD_NUM_CLIENT_MIN ( 1 )
+#define CFG_DHCP_SERVER_OFFLOAD_NUM_CLIENT_MAX ( 4 )
+#define CFG_DHCP_SERVER_OFFLOAD_NUM_CLIENT_DEFAULT ( 4 )
+
+/* Start address of the pool */
+#define CFG_DHCP_SERVER_OFFLOAD_START_LSB_NAME "gDHCPStartLsb"
+#define CFG_DHCP_SERVER_OFFLOAD_START_LSB_MIN ( 100 )
+#define CFG_DHCP_SERVER_OFFLOAD_START_LSB_MAX ( 255 )
+#define CFG_DHCP_SERVER_OFFLOAD_START_LSB_DEFAULT ( 100 )
+
+/* DHCP Server IP*/
+#define CFG_DHCP_SERVER_IP_NAME "gDHCPServerIP"
+#define CFG_DHCP_SERVER_IP_DEFAULT "192.168.43.1"
+#endif /* DHCP_SERVER_OFFLOAD */
+
+#ifdef MDNS_OFFLOAD
+/*
+ * Enable/Disable multicast DNS Offload
+ * 0x0 - Disable mDNS (Default)
+ * 0x1 - Enable mDNS
+ */
+#define CFG_MDNS_OFFLOAD_SUPPORT_NAME "gMDNSOffloadEnable"
+#define CFG_MDNS_OFFLOAD_SUPPORT_MIN ( 0 )
+#define CFG_MDNS_OFFLOAD_SUPPORT_MAX ( 1 )
+#define CFG_MDNS_OFFLOAD_SUPPORT_ENABLE ( 1 )
+#define CFG_MDNS_OFFLOAD_SUPPORT_DEFAULT ( 1 )
+
+/* Set FQDN string for mDNS */
+#define CFG_MDNS_FQDN_NAME "gMDNSFqdn"
+#define CFG_MDNS_FQDN_DEFAULT "_GoProRemote._tcp.local"
+
+/* Set UFQDN string for mDNS */
+#define CFG_MDNS_UNIQUE_FQDN_NAME "gMDNSUniqueFqdn"
+#define CFG_MDNS_UNIQUE_FQDN_DEFAULT "service._GoProRemote._tcp.local"
+
+/* Set the response Type A to mDNS queries */
+#define CFG_MDNS_RESPONSE_TYPE_A_NAME "gMDNSResponseTypeA"
+#define CFG_MDNS_RESPONSE_TYPE_A_DEFAULT "goprobp-D89685121212.local"
+
+#define CFG_MDNS_RESPONSE_TYPE_A_IPV4_NAME "gMDNSResponseTypeAIpv4Addr"
+#define CFG_MDNS_RESPONSE_TYPE_A_IPV4_MIN ( 1 )
+#define CFG_MDNS_RESPONSE_TYPE_A_IPV4_MAX ( 0xffffffff )
+#define CFG_MDNS_RESPONSE_TYPE_A_IPV4_DEFAULT ( 0xc0a80102 )
+
+/* Set the response Type TXT to mDNS queries */
+#define CFG_MDNS_RESPONSE_TYPE_TXT_NAME "gMDNSResponseTypeTXT"
+#define CFG_MDNS_RESPONSE_TYPE_TXT_DEFAULT "GoProBP-D89685121212._GoProRemote._tcp.local"
+
+#define CFG_MDNS_RESPONSE_TYPE_TXT_CNT_NAME "gMDNSResponseTypeTXTContent"
+#define CFG_MDNS_RESPONSE_TYPE_TXT_CNT_DEFAULT "Device=HERO 3+-BAWA Model=BAWA Version=HD3.11.02.00 Wifi Version=4.0.36.0 Protocol Version=2"
+
+/* Set the response Type PTR to mDNS queries */
+#define CFG_MDNS_RESPONSE_TYPE_PTR_NAME "gMDNSResponseTypePTR"
+#define CFG_MDNS_RESPONSE_TYPE_PTR_DEFAULT "_GoProRemote._tcp.local"
+
+#define CFG_MDNS_RESPONSE_TYPE_PTR_DN_NAME "gMDNSResponseTypePTRDomainName"
+#define CFG_MDNS_RESPONSE_TYPE_PTR_DN_DEFAULT "GoProBP-D89685121212._GoProRemote._tcp.local"
+
+/* Set the response Type SRV to mDNS queries */
+#define CFG_MDNS_RESPONSE_TYPE_SRV_NAME "gMDNSResponseTypeSRV"
+#define CFG_MDNS_RESPONSE_TYPE_SRV_DEFAULT "GoProBP-D89685121212._GoProRemote._tcp.local"
+
+/* Set the response Type SRV Priority to mDNS queries */
+#define CFG_MDNS_RESPONSE_TYPE_SRV_PRIORITY_NAME "gMDNSResponseTypeSRVPriority"
+#define CFG_MDNS_RESPONSE_TYPE_SRV_PRIORITY_MIN ( 0 )
+#define CFG_MDNS_RESPONSE_TYPE_SRV_PRIORITY_MAX ( 65535 )
+#define CFG_MDNS_RESPONSE_TYPE_SRV_PRIORITY_DEFAULT ( 0 )
+
+/* Set the response Type SRV Weight to mDNS queries */
+#define CFG_MDNS_RESPONSE_TYPE_SRV_WEIGHT_NAME "gMDNSResponseTypeSRVWeight"
+#define CFG_MDNS_RESPONSE_TYPE_SRV_WEIGHT_MIN ( 0 )
+#define CFG_MDNS_RESPONSE_TYPE_SRV_WEIGHT_MAX ( 65525 )
+#define CFG_MDNS_RESPONSE_TYPE_SRV_WEIGHT_DEFAULT ( 0 )
+
+/* Set the response Type SRV Port to mDNS queries */
+#define CFG_MDNS_RESPONSE_TYPE_SRV_PORT_NAME "gMDNSResponseTypeSRVPort"
+#define CFG_MDNS_RESPONSE_TYPE_SRV_PORT_MIN ( 0 )
+#define CFG_MDNS_RESPONSE_TYPE_SRV_PORT_MAX ( 65525 )
+#define CFG_MDNS_RESPONSE_TYPE_SRV_PORT_DEFAULT ( 80 )
+
+/* Set the response Type SRV Target to mDNS queries */
+#define CFG_MDNS_RESPONSE_TYPE_SRV_TGT_NAME "gMDNSResponseTypeSRVTarget"
+#define CFG_MDNS_RESPONSE_TYPE_SRV_TGT_DEFAULT "goprobp-D89685121212.local"
+#endif /* MDNS_OFFLOAD */
/*
* gExtScanConcMode is used to manage EXT Scan during concurrency
@@ -2871,11 +3042,6 @@ This feature requires the dependent cfg.ini "gRoamPrefer5GHz" set to 1 */
#define CFG_SAP_PROBE_RESP_OFFLOAD_MAX (1)
#define CFG_SAP_PROBE_RESP_OFFLOAD_DEFAULT (1)
-#define CFG_SAP_INTERNAL_RESTART_NAME "gEnableSapInternalRestart"
-#define CFG_SAP_INTERNAL_RESTART_MIN (0)
-#define CFG_SAP_INTERNAL_RESTART_MAX (1)
-#define CFG_SAP_INTERNAL_RESTART_DEFAULT (1)
-
/*
* gDisableScanDuringSco is used to disable/enable scan during SCO call
* This can be useful to avoid glitches because of EXIT_IMPS invoked by scan
@@ -2888,6 +3054,44 @@ This feature requires the dependent cfg.ini "gRoamPrefer5GHz" set to 1 */
#define CFG_DISABLE_SCAN_DURING_SCO_MAX (1)
#define CFG_DISABLE_SCAN_DURING_SCO_DEFAULT (0)
+#define CFG_SAP_INTERNAL_RESTART_NAME "gEnableSapInternalRestart"
+#define CFG_SAP_INTERNAL_RESTART_MIN (0)
+#define CFG_SAP_INTERNAL_RESTART_MAX (1)
+#define CFG_SAP_INTERNAL_RESTART_DEFAULT (1)
+
+/*
+ * maximum interval (in seconds) for a
+ * single scan plan supported by the device.
+ */
+#define CFG_MAX_SCHED_SCAN_PLAN_INT_NAME "g_max_sched_scan_plan_int"
+#define CFG_MAX_SCHED_SCAN_PLAN_INT_MIN (1)
+#define CFG_MAX_SCHED_SCAN_PLAN_INT_MAX (7200)
+#define CFG_MAX_SCHED_SCAN_PLAN_INT_DEFAULT (3600)
+
+/*
+ * maximum number of iterations for a single
+ * scan plan supported by the device.
+ */
+#define CFG_MAX_SCHED_SCAN_PLAN_ITRNS_NAME "g_max_sched_scan_plan_itrns"
+#define CFG_MAX_SCHED_SCAN_PLAN_ITRNS_MIN (1)
+#define CFG_MAX_SCHED_SCAN_PLAN_ITRNS_MAX (100)
+#define CFG_MAX_SCHED_SCAN_PLAN_ITRNS_DEFAULT (10)
+
+/*
+ * gEnableLFRMBB is used to disable/enable LFR Make before Break
+ * 1: Enable LFR Make before Break
+ * 0: Disable LFR Make before Break
+ */
+#define CFG_ENABLE_LFR_MBB "gEnableLFRMBB"
+#define CFG_ENABLE_LFR_MBB_MIN (0)
+#define CFG_ENABLE_LFR_MBB_MAX (1)
+#define CFG_ENABLE_LFR_MBB_DEFAULT (0)
+
+/* Value for TRIGGER_NULLFRAME_BEFORE_HB.*/
+#define CFG_TRIGGER_NULLFRAME_BEFORE_HB_NAME "gTriggerNullframeBeforeHb"
+#define CFG_TRIGGER_NULLFRAME_BEFORE_HB_MIN (0)
+#define CFG_TRIGGER_NULLFRAME_BEFORE_HB_MAX (1)
+#define CFG_TRIGGER_NULLFRAME_BEFORE_HB_DEFAULT (0)
/*---------------------------------------------------------------------------
Type declarations
@@ -2964,6 +3168,7 @@ typedef struct
v_U32_t nAutoBmpsTimerValue;
eHddDot11Mode dot11Mode;
v_U32_t nChannelBondingMode24GHz;
+ bool override_ht20_40_24g;
v_U32_t nChannelBondingMode5GHz;
v_U32_t MaxRxAmpduFactor;
v_U32_t nBAAgingTimerInterval;
@@ -3032,6 +3237,7 @@ typedef struct
v_U16_t nNeighborResultsRefreshPeriod;
v_U16_t nEmptyScanRefreshPeriod;
v_U8_t nNeighborInitialForcedRoamTo5GhEnable;
+ v_U8_t nWeakZoneRssiThresholdForRoam;
#endif
//Additional Handoff params
@@ -3119,6 +3325,11 @@ typedef struct
v_U32_t PERtimerThreshold;
v_U32_t PERroamRxPktsThreshold;
#endif
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ tANI_BOOLEAN enable_lfr_mbb;
+#endif
+
hdd_wmm_classification_t PktClassificationBasis; // DSCP or 802.1Q
v_BOOL_t bImplicitQosEnabled;
@@ -3419,6 +3630,7 @@ typedef struct
v_BOOL_t toggleArpBDRates;
v_U32_t btcStaticOppWlanIdleWlanLen;
v_U32_t btcStaticOppWlanIdleBtLen;
+ v_U32_t btc_disable_wlan_link_critical;
v_U32_t linkFailTimeout;
v_U32_t linkFailTxCnt;
v_BOOL_t ignorePeerHTopMode;
@@ -3434,6 +3646,28 @@ typedef struct
v_U8_t max_chan_for_dwell_time_cfg;
v_U16_t tdls_enable_defer_time;
v_U8_t boffset_correction_enable;
+#ifdef DHCP_SERVER_OFFLOAD
+ v_BOOL_t enable_dhcp_srv_offload;
+ v_U32_t dhcp_max_num_clients;
+ v_U8_t dhcp_srv_ip[IPADDR_STRING_LENGTH];
+ v_U8_t dhcp_start_lsb;
+#endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+ uint32_t enable_mdns_offload;
+ uint8_t mdns_fqdn[MAX_MDNS_FQDN_LEN];
+ uint8_t mdns_uniquefqdn[MAX_MDNS_FQDN_LEN];
+ uint8_t mdns_resp_type_a[MAX_MDNS_RESP_LEN];
+ uint32_t mdns_resp_type_a_ipv4;
+ uint8_t mdns_resp_type_txt[MAX_MDNS_RESP_LEN];
+ uint8_t mdns_resp_type_txt_content[MAX_MDNS_RESP_LEN];
+ uint8_t mdns_resp_type_ptr[MAX_MDNS_RESP_LEN];
+ uint8_t mdns_resp_type_ptr_dname[MAX_MDNS_RESP_LEN];
+ uint8_t mdns_resp_type_srv[MAX_MDNS_RESP_LEN];
+ uint16_t mdns_resp_type_srv_priority;
+ uint16_t mdns_resp_type_srv_weight;
+ uint16_t mdns_resp_type_srv_port;
+ uint8_t mdns_resp_type_srv_target[MAX_MDNS_RESP_LEN];
+#endif /* MDNS_OFFLOAD */
uint32_t enable_edca_params;
uint32_t edca_vo_cwmin;
uint32_t edca_vi_cwmin;
@@ -3449,8 +3683,17 @@ typedef struct
uint32_t edca_be_aifs;
v_BOOL_t sendMgmtPktViaWQ5;
v_BOOL_t sap_probe_resp_offload;
- v_BOOL_t sap_internal_restart;
v_BOOL_t disable_scan_during_sco;
+ v_BOOL_t sap_internal_restart;
+#ifdef SAP_AUTH_OFFLOAD
+ bool enable_sap_auth_offload;
+ uint32_t sap_auth_offload_sec_type;
+ uint8_t sap_auth_offload_key[WLAN_PSK_STRING_LENGTH];
+#endif /* SAP_AUTH_OFFLOAD */
+ uint32_t max_sched_scan_plan_interval;
+ uint32_t max_sched_scan_plan_iterations;
+ uint32_t sta_auth_retries_for_code17;
+ uint32_t trigger_nullframe_before_hb;
} hdd_config_t;
/*---------------------------------------------------------------------------
@@ -3464,6 +3707,16 @@ eCsrPhyMode hdd_cfg_xlate_to_csr_phy_mode( eHddDot11Mode dot11Mode );
VOS_STATUS hdd_execute_config_command(hdd_context_t *pHddCtx, char *command);
tANI_BOOLEAN hdd_is_okc_mode_enabled(hdd_context_t *pHddCtx);
+VOS_STATUS hdd_string_to_u8_array(char *str, tANI_U8 *intArray, tANI_U8 *len,
+ tANI_U8 intArrayMaxLen, char *seperator);
+
+#ifdef MDNS_OFFLOAD
+int hdd_string_to_string_array(char *data, uint8_t *datalist,
+ char separator, uint8_t *num_entries,
+ uint8_t max_entries,
+ uint8_t max_len_entry);
+#endif /* MDNS_OFFLOAD */
+
#define VAR_OFFSET( _Struct, _Var ) (offsetof(_Struct, _Var))
#define VAR_SIZE( _Struct, _Var ) (sizeof(((_Struct *)0)->_Var))
diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_cfg80211.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_cfg80211.h
index 6307b18ccce..ef99dd041de 100644
--- a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_cfg80211.h
+++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_cfg80211.h
@@ -110,6 +110,7 @@
#define NUM_RADIOS 0x1
#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
+
typedef struct {
u8 element_id;
u8 len;
@@ -172,6 +173,7 @@ enum qca_nl80211_vendor_subcmds {
/* Get Concurrency Matrix */
QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX = 42,
+ QCA_NL80211_VENDOR_SUBCMD_APFIND = 52,
/* Start Wifi Logger */
QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START = 62,
@@ -200,12 +202,159 @@ enum qca_nl80211_vendor_subcmds {
QCA_NL80211_VENDOR_SUBCMD_SETBAND = 105,
+ /* send BSS Information */
+ QCA_NL80211_VENDOR_SUBCMD_GET_STATION = 121,
+
/* Start / Stop the NUD stats collections */
QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET = 149,
/* Get the NUD stats, represented by the enum qca_attr_nud_stats_get */
QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET = 150,
};
+/**
+ * enum qca_wlan_vendor_attr_get_station - Sub commands used by
+ * QCA_NL80211_VENDOR_SUBCMD_GET_STATION to get the corresponding
+ * station information. The information obtained through these
+ * commands signify the current info in connected state and
+ * latest cached information during the connected state , if queried
+ * when in disconnected state.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO: bss info
+ * @QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON: assoc fail reason
+ */
+enum qca_wlan_vendor_attr_get_station {
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID = 0,
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO,
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON,
+
+ /* keep last */
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_AFTER_LAST,
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX =
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_802_11_mode - dot11 mode
+ * @QCA_WLAN_802_11_MODE_INVALID: Invalid dot11 mode
+ * @QCA_WLAN_802_11_MODE_11A: mode A
+ * @QCA_WLAN_802_11_MODE_11B: mode B
+ * @QCA_WLAN_802_11_MODE_11G: mode G
+ * @QCA_WLAN_802_11_MODE_11N: mode N
+ * @QCA_WLAN_802_11_MODE_11AC: mode AC
+ */
+enum qca_wlan_802_11_mode {
+ QCA_WLAN_802_11_MODE_INVALID,
+ QCA_WLAN_802_11_MODE_11A,
+ QCA_WLAN_802_11_MODE_11B,
+ QCA_WLAN_802_11_MODE_11G,
+ QCA_WLAN_802_11_MODE_11N,
+ QCA_WLAN_802_11_MODE_11AC,
+};
+
+/**
+ * enum qca_wlan_auth_type - Authentication key management type
+ * @QCA_WLAN_AUTH_TYPE_INVALID: Invalid key management type
+ * @QCA_WLAN_AUTH_TYPE_OPEN: Open key
+ * @QCA_WLAN_AUTH_TYPE_SHARED: shared key
+ * @QCA_WLAN_AUTH_TYPE_WPA: wpa key
+ * @QCA_WLAN_AUTH_TYPE_WPA_PSK: wpa psk key
+ * @QCA_WLAN_AUTH_TYPE_WPA_NONE: wpa none key
+ * @QCA_WLAN_AUTH_TYPE_RSN: rsn key
+ * @QCA_WLAN_AUTH_TYPE_RSN_PSK: rsn psk key
+ * @QCA_WLAN_AUTH_TYPE_FT: ft key
+ * @QCA_WLAN_AUTH_TYPE_FT_PSK: ft psk key
+ * @QCA_WLAN_AUTH_TYPE_SHA256: shared 256 key
+ * @QCA_WLAN_AUTH_TYPE_SHA256_PSK: shared 256 psk
+ * @QCA_WLAN_AUTH_TYPE_WAI: wai key
+ * @QCA_WLAN_AUTH_TYPE_WAI_PSK wai psk key
+ * @QCA_WLAN_AUTH_TYPE_CCKM_WPA: cckm wpa key
+ * @QCA_WLAN_AUTH_TYPE_CCKM_RSN: cckm rsn key
+ */
+enum qca_wlan_auth_type {
+ QCA_WLAN_AUTH_TYPE_INVALID,
+ QCA_WLAN_AUTH_TYPE_OPEN,
+ QCA_WLAN_AUTH_TYPE_SHARED,
+ QCA_WLAN_AUTH_TYPE_WPA,
+ QCA_WLAN_AUTH_TYPE_WPA_PSK,
+ QCA_WLAN_AUTH_TYPE_WPA_NONE,
+ QCA_WLAN_AUTH_TYPE_RSN,
+ QCA_WLAN_AUTH_TYPE_RSN_PSK,
+ QCA_WLAN_AUTH_TYPE_FT,
+ QCA_WLAN_AUTH_TYPE_FT_PSK,
+ QCA_WLAN_AUTH_TYPE_SHA256,
+ QCA_WLAN_AUTH_TYPE_SHA256_PSK,
+ QCA_WLAN_AUTH_TYPE_WAI,
+ QCA_WLAN_AUTH_TYPE_WAI_PSK,
+ QCA_WLAN_AUTH_TYPE_CCKM_WPA,
+ QCA_WLAN_AUTH_TYPE_CCKM_RSN,
+ QCA_WLAN_AUTH_TYPE_AUTOSWITCH,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_get_station_info - Station Info queried
+ * through QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_INVALID: Invalid Attribute
+ * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_LINK_STANDARD_NL80211_ATTR:
+ * Get the standard NL attributes Nested with this attribute.
+ * Ex : Query BW , BITRATE32 , NSS , Signal , Noise of the Link -
+ * NL80211_ATTR_SSID / NL80211_ATTR_SURVEY_INFO (Connected Channel) /
+ * NL80211_ATTR_STA_INFO
+ * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AP_STANDARD_NL80211_ATTR:
+ * Get the standard NL attributes Nested with this attribute.
+ * Ex : Query HT/VHT Capability advertized by the AP.
+ * NL80211_ATTR_VHT_CAPABILITY / NL80211_ATTR_HT_CAPABILITY
+ * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ROAM_COUNT:
+ * Number of successful Roam attempts before a
+ * disconnect, Unsigned 32 bit value
+ * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AKM:
+ * Authentication Key Management Type used for the connected session.
+ * Signified by enum qca_wlan_auth_type
+ * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_802_11_MODE: 802.11 Mode of the
+ * connected Session, signified by enum qca_wlan_802_11_mode
+ * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AP_HS20_INDICATION:
+ * HS20 Indication Element
+ * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ASSOC_FAIL_REASON:
+ * Status Code Corresponding to the Association Failure.
+ * Unsigned 32 bit value.
+ */
+enum qca_wlan_vendor_attr_get_station_info {
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_INVALID = 0,
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_LINK_STANDARD_NL80211_ATTR,
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AP_STANDARD_NL80211_ATTR,
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ROAM_COUNT,
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AKM,
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_802_11_MODE,
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AP_HS20_INDICATION,
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_HT_OPERATION,
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_VHT_OPERATION,
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ASSOC_FAIL_REASON,
+ /* keep last */
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AFTER_LAST,
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_MAX =
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AFTER_LAST - 1,
+};
+
+/* define short names for get station info attributes */
+#define LINK_INFO_STANDARD_NL80211_ATTR \
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_LINK_STANDARD_NL80211_ATTR
+#define AP_INFO_STANDARD_NL80211_ATTR \
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AP_STANDARD_NL80211_ATTR
+#define INFO_ROAM_COUNT \
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ROAM_COUNT
+#define INFO_AKM \
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AKM
+#define WLAN802_11_MODE \
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_802_11_MODE
+#define AP_INFO_HS20_INDICATION \
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AP_HS20_INDICATION
+#define HT_OPERATION \
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_HT_OPERATION
+#define VHT_OPERATION \
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_VHT_OPERATION
+#define INFO_ASSOC_FAIL_REASON \
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ASSOC_FAIL_REASON
+
enum qca_nl80211_vendor_subcmds_index {
#ifdef FEATURE_WLAN_CH_AVOID
QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
@@ -291,7 +440,7 @@ enum qca_attr_nud_stats_get {
QCA_ATTR_NUD_STATS_GET_LAST,
QCA_ATTR_NUD_STATS_GET_MAX =
QCA_ATTR_NUD_STATS_GET_LAST - 1,
-};
+ };
enum qca_wlan_vendor_attr
{
@@ -1162,6 +1311,10 @@ enum qca_wlan_vendor_config {
QCA_WLAN_VENDOR_ATTR_CONFIG_FINE_TIME_MEASUREMENT,
QCA_WLAN_VENDOR_ATTR_CONFIG_TX_RATE,
QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS,
+ /* 8-bit unsigned value to set the beacon miss threshold in 2.4 GHz */
+ QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24 = 37,
+ /* 8-bit unsigned value to set the beacon miss threshold in 5 GHz */
+ QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5 = 38,
/* keep last */
QCA_WLAN_VENDOR_ATTR_CONFIG_LAST,
QCA_WLAN_VENDOR_ATTR_CONFIG_MAX =
@@ -1508,4 +1661,5 @@ int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
#endif
int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter);
+int wlan_hdd_try_disconnect(hdd_adapter_t *pAdapter);
#endif
diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_hostapd.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_hostapd.h
index ed52105fc37..1c9aec96211 100644
--- a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_hostapd.h
+++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_hostapd.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -116,8 +116,34 @@ void hdd_restart_softap (hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter);
void hdd_hostapd_ch_avoid_cb(void *pAdapter, void *indParam);
#endif /* FEATURE_WLAN_CH_AVOID */
int hdd_del_all_sta(hdd_adapter_t *pAdapter);
-
void hdd_sap_indicate_disconnect_for_sta(hdd_adapter_t *adapter);
void hdd_sap_destroy_timers(hdd_adapter_t *adapter);
+#ifdef SAP_AUTH_OFFLOAD
+bool hdd_set_sap_auth_offload(hdd_adapter_t *pHostapdAdapter,
+ bool enabled);
+#else
+static inline bool
+hdd_set_sap_auth_offload(hdd_adapter_t *pHostapdAdapter, bool enabled)
+{
+}
+#endif
+
+/**
+ * hdd_check_for_unsafe_ch() - Check the current operating channel with
+ * unsafe channel list.
+ * @phostapd_adapter : Pointer to HDD adapter.
+ * @hdd_ctx: pointer to hdd context.
+ *
+ * Check the current operating chennel of SAP with unsafe channel list
+ * and Restart the SAP on safe channel if currently SAP is
+ * on unsafe channel.
+ *
+ * Return : None
+ */
+void hdd_check_for_unsafe_ch(hdd_adapter_t *phostapd_adapter,
+ hdd_context_t *hdd_ctx);
+void hdd_force_scc_restart_sap(hdd_adapter_t *adapter,
+ hdd_context_t *hdd_ctx, tANI_U8 channelId);
+
#endif // end #if !defined( WLAN_HDD_HOSTAPD_H )
diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_main.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_main.h
index 91d3e4b507e..4b9c5a7b974 100644
--- a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_main.h
+++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_main.h
@@ -106,11 +106,12 @@
/** Maximum time(ms)to wait for disconnect to complete **/
#define WLAN_WAIT_TIME_DISCONNECT 5000
#define WLAN_WAIT_TIME_STATS 800
-#define WLAN_WAIT_TIME_POWER 800
+#define WLAN_WAIT_TIME_POWER 5000
#define WLAN_WAIT_TIME_COUNTRY 1000
#define WLAN_WAIT_TIME_CHANNEL_UPDATE 600
#define FW_STATE_WAIT_TIME 500
#define FW_STATE_RSP_LEN 100
+
/* Amount of time to wait for sme close session callback.
This value should be larger than the timeout used by WDI to wait for
a response from WCNSS */
@@ -161,6 +162,7 @@
#define hddLog(level, args...) VOS_TRACE( VOS_MODULE_ID_HDD, level, ## args)
#define ENTER() VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Enter:%s", __func__)
#define EXIT() VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Exit:%s", __func__)
+#define ENTER_DEV(dev) VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Enter:%s dev_name: %s", __func__, (dev)->name)
#define WLAN_HDD_GET_PRIV_PTR(__dev__) (hdd_adapter_t*)(netdev_priv((__dev__)))
@@ -246,6 +248,27 @@ typedef v_U8_t tWlanHddMacAddr[HDD_MAC_ADDR_LEN];
#define WLAN_WAIT_TIME_EXTSCAN 1000
+#define HDD_MAX_STA_COUNT (HAL_NUM_STA)
+
+#ifdef MDNS_OFFLOAD
+#define MDNS_HEADER_LEN 12
+#define MDNS_FQDN_TYPE_GENERAL 0
+#define MDNS_FQDN_TYPE_UNIQUE 1
+#define MAX_NUM_FIELD_DOMAINNAME 6
+#define MAX_LEN_DOMAINNAME_FIELD 64
+#define MAX_MDNS_RESP_TYPE 6
+#define MDNS_TYPE_A 1
+#define MDNS_TYPE_TXT 16
+#define MDNS_TYPE_PTR 12
+#define MDNS_TYPE_PTR_DNAME 13
+#define MDNS_TYPE_SRV 33
+#define MDNS_TYPE_SRV_TARGET 34
+#define MDNS_CLASS 1
+#define MDNS_TTL 5
+#endif /* MDNS_OFFLOAD */
+
+#define HDD_MIN_TX_POWER (-100) /* minimum tx power */
+#define HDD_MAX_TX_POWER (+100) /* maximum tx power */
/*
* Generic asynchronous request/response support
*
@@ -394,8 +417,8 @@ typedef enum
typedef struct hdd_arp_stats_s
{
- uint16 tx_arp_req_count;
- uint16 rx_arp_rsp_count;
+ uint16 txCount;
+ uint16 rxCount;
uint16 txDropped;
uint16 rxDropped;
uint16 rxDelivered;
@@ -799,6 +822,7 @@ struct hdd_station_ctx
hdd_ibss_peer_info_t ibss_peer_info;
v_BOOL_t hdd_ReassocScenario;
+ v_BOOL_t get_mgmt_log_sent;
};
@@ -813,7 +837,82 @@ typedef struct hdd_hostapd_state_s
} hdd_hostapd_state_t;
+#ifdef DHCP_SERVER_OFFLOAD
+typedef struct hdd_dhcp_state_s
+{
+ VOS_STATUS dhcp_offload_status;
+ vos_event_t vos_event;
+} hdd_dhcp_state_t;
+#endif /* DHCP_SERVER_OFFLOAD */
+
+#ifdef MDNS_OFFLOAD
+typedef struct hdd_mdns_state_s
+{
+ VOS_STATUS mdns_enable_status;
+ VOS_STATUS mdns_fqdn_status;
+ VOS_STATUS mdns_resp_status;
+ vos_event_t vos_event;
+} hdd_mdns_state_t;
+#endif /* MDNS_OFFLOAD */
+
+#ifdef WLAN_FEATURE_TSF
+
+#define HDD_TSF_CAP_REQ_TIMEOUT 2000
+#define HDD_TSF_GET_REQ_TIMEOUT 2000
+
+/**
+ * enum hdd_tsf_get_state - status of get tsf action
+ *
+ * TSF_RETURN: get tsf
+ * TSF_STA_NOT_CONNECTED_NO_TSF: sta not connected to ap
+ * TSF_NOT_RETURNED_BY_FW: fw not returned tsf
+ * TSF_CURRENT_IN_CAP_STATE: driver in capture state
+ * TSF_CAPTURE_FAIL: capture fail
+ * TSF_GET_FAIL: get fail
+ * TSF_RESET_GPIO_FAIL: GPIO reset fail
+ * TSF_SAP_NOT_STARTED_NO_TSF SAP not started
+ */
+enum hdd_tsf_get_state {
+ TSF_RETURN = 0,
+ TSF_STA_NOT_CONNECTED_NO_TSF,
+ TSF_NOT_RETURNED_BY_FW,
+ TSF_CURRENT_IN_CAP_STATE,
+ TSF_CAPTURE_FAIL,
+ TSF_GET_FAIL,
+ TSF_RESET_GPIO_FAIL,
+ TSF_SAP_NOT_STARTED_NO_TSF
+};
+
+/**
+ * enum hdd_tsf_capture_state - status of capture
+ *
+ * TSF_IDLE: idle
+ * TSF__CAP_STATE: current is in capture state
+ */
+enum hdd_tsf_capture_state {
+ TSF_IDLE = 0,
+ TSF_CAP_STATE
+};
+
+/**
+ * struct hdd_tsf_ctx_s - TSF capture ctx
+ * @tsf_get_state : tsf action enum
+ * @tsf_capture_state: tsf capture state enum
+ * @tsf_capture_done_event : Indicate tsf completion
+ * @tsf_high : Higher 32-bit for 64-bit tsf
+ * @tsf_lo : Lower 32-bit for 64-bit tsf
+ *
+ */
+struct hdd_tsf_ctx_s {
+ enum hdd_tsf_get_state tsf_get_state;
+ enum hdd_tsf_capture_state tsf_capture_state;
+ vos_event_t tsf_capture_done_event;
+ vos_spin_lock_t tsf_lock;
+ uint32_t tsf_high;
+ uint32_t tsf_low;
+};
+#endif /* WLAN_FEATURE_TSF */
/*
* Per station structure kept in HDD for multiple station support for SoftAP
*/
@@ -994,6 +1093,8 @@ typedef enum
#endif
+#define HDD_SCAN_REJECT_RATE_LIMIT 5
+
/*
* @eHDD_SCAN_REJECT_DEFAULT: default value
* @eHDD_CONNECTION_IN_PROGRESS: connection is in progress
@@ -1110,6 +1211,9 @@ struct hdd_adapter_s
struct completion ibss_peer_info_comp;
#endif /* WLAN_FEATURE_RMC */
+ /* completion variable for wlan suspend */
+ struct completion wlan_suspend_comp_var;
+
/* Track whether the linkup handling is needed */
v_BOOL_t isLinkUpSvcNeeded;
@@ -1148,7 +1252,10 @@ struct hdd_adapter_s
#ifdef FEATURE_WLAN_WAPI
hdd_wapi_info_t wapi_info;
#endif
-
+
+ /* Keep track ns offload count */
+ v_U8_t ns_slots;
+
v_S7_t rssi;
v_S7_t rssi_on_disconnect;
@@ -1249,9 +1356,18 @@ struct hdd_adapter_s
/* Currently used antenna Index*/
int antennaIndex;
- bool nud_set_arp_stats;
- bool con_status;
- bool dad;
+#ifdef DHCP_SERVER_OFFLOAD
+ hdd_dhcp_state_t dhcp_status;
+#endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+ hdd_mdns_state_t mdns_status;
+#endif /* MDNS_OFFLOAD */
+
+#ifdef WLAN_FEATURE_TSF
+ struct hdd_tsf_ctx_s tsf_cap_ctx;
+#endif
+ bool con_status;
+ bool dad;
};
#define WLAN_HDD_GET_STATION_CTX_PTR(pAdapter) (&(pAdapter)->sessionCtx.station)
@@ -1369,6 +1485,7 @@ struct hdd_ll_stats_context {
struct hdd_nud_stats_context {
struct completion response_event;
};
+
#ifdef WLAN_FEATURE_EXTSCAN
/**
* struct hdd_ext_scan_context - hdd ext scan context
@@ -1504,6 +1621,8 @@ struct hdd_context_s
v_BOOL_t hdd_wlan_suspended;
bool rx_wow_dump;
+
+ uint8_t bad_sta[HDD_MAX_STA_COUNT];
spinlock_t filter_lock;
@@ -1689,6 +1808,8 @@ struct hdd_context_s
scan_reject_states last_scan_reject_reason;
v_TIME_t last_scan_reject_timestamp;
v_U8_t scan_reject_cnt;
+ bool is_ap_mode_wow_supported;
+ bool is_fatal_event_log_sup;
uint32_t track_arp_ip;
};
@@ -1757,6 +1878,20 @@ typedef enum
WLAN_FW_MEM_DUMP_EN = 1<<6,
} WLAN_ENABLE_HW_FW_LOG_TYPE;
+#ifdef MDNS_OFFLOAD
+/* Offload struct */
+struct hdd_mdns_resp_info {
+ uint8_t num_entries;
+ uint8_t *data;
+ uint16_t *offset;
+};
+
+struct hdd_mdns_resp_matched {
+ uint8_t num_matched;
+ uint8_t type;
+};
+#endif /* MDNS_OFFLOAD */
+
/*---------------------------------------------------------------------------
Function declarations and documenation
-------------------------------------------------------------------------*/
@@ -2040,7 +2175,55 @@ void wlan_hdd_defer_scan_init_work(hdd_context_t *pHddCtx,
unsigned long delay);
int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
const tANI_U8 channel, const handoff_src src);
+#ifdef DHCP_SERVER_OFFLOAD
+VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
+ bool re_init);
+#endif
+#ifdef MDNS_OFFLOAD
+bool wlan_hdd_set_mdns_offload(hdd_adapter_t *adapter);
+#else
+static inline bool wlan_hdd_set_mdns_offload(hdd_adapter_t *adapter)
+{
+ return FALSE;
+}
+#endif /* MDNS_OFFLOAD */
void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter);
+/**
+ * hdd_drv_cmd_validate() - Validates for space in hdd driver command
+ * @command: pointer to input data (its a NULL terminated string)
+ * @len: length of command name
+ *
+ * This function checks for space after command name and if no space
+ * is found returns error.
+ *
+ * Return: 0 for success non-zero for failure
+ */
+int hdd_drv_cmd_validate(tANI_U8 *command, int len);
+
+#ifdef WLAN_FEATURE_TSF
+void wlan_hdd_tsf_init(hdd_adapter_t *adapter);
+int hdd_capture_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len);
+int hdd_indicate_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len);
+#else
+static inline void
+wlan_hdd_tsf_init(hdd_adapter_t *adapter)
+{
+ return;
+}
+
+static inline int
+hdd_indicate_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
+{
+ return -ENOTSUPP;
+}
+
+static inline int
+hdd_capture_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
+{
+ return -ENOTSUPP;
+}
+#endif
+int hdd_dhcp_mdns_offload(hdd_adapter_t *adapter);
#endif // end #if !defined( WLAN_HDD_MAIN_H )
diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_oemdata.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_oemdata.h
index 5b68187dfbe..47522e172ee 100644
--- a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_oemdata.h
+++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_oemdata.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -71,6 +71,7 @@ struct iw_oem_data_rsp
};
int oem_activate_service(void *pAdapter);
+void oem_deactivate_service(void);
int iw_get_oem_data_cap(struct net_device *dev, struct iw_request_info *info,
union iwreq_data *wrqu, char *extra);
diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_tdls.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_tdls.h
index bc58f4ad459..c9731f1d9dc 100644
--- a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_tdls.h
+++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_tdls.h
@@ -539,4 +539,6 @@ tdlsConnInfo_t *wlan_hdd_get_conn_info(hdd_context_t *pHddCtx,
v_VOID_t wlan_hdd_tdls_initiator_wait_cb(v_PVOID_t userData);
+void wlan_hdd_get_tdls_stats(hdd_adapter_t *pAdapter);
+
#endif // __HDD_TDSL_H
diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_tx_rx.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_tx_rx.h
index 68f7174b4ba..06c5accb2ff 100644
--- a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_tx_rx.h
+++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_tx_rx.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2015, 2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -400,4 +400,14 @@ static inline void wlan_hdd_log_eapol(struct sk_buff *skb,
}
#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+/**
+ * hdd_rx_fwd_eapol() - forward cached eapol frames
+ * @vosContext : pointer to vos global context
+ * @pVosPacket: pointer to vos packet
+ *
+ * Return: None
+ *
+ */
+void hdd_rx_fwd_eapol(v_VOID_t *vosContext, vos_pkt_t *pVosPacket);
+
#endif // end #if !defined( WLAN_HDD_TX_RX_H )
diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_wext.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_wext.h
index fe8bfed2118..1a58dc027fd 100644
--- a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_wext.h
+++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_wext.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -463,6 +463,6 @@ void* wlan_hdd_change_country_code_callback(void *pAdapter);
int hdd_setBand(struct net_device *dev, u8 ui_band);
int hdd_setBand_helper(struct net_device *dev, const char *command);
VOS_STATUS wlan_hdd_get_frame_logs(hdd_adapter_t *pAdapter, v_U8_t flag);
-int wlan_hdd_set_proximity(int set_value);
+int wlan_hdd_set_proximity(int set_value, tHalHandle hal);
#endif // __WEXT_IW_H__
diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_assoc.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_assoc.c
index b7c935de763..6a962d4f373 100644
--- a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_assoc.c
+++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_assoc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -266,6 +266,487 @@ static inline void hdd_connSaveConnectedBssType( hdd_station_ctx_t *pHddStaCtx,
}
+/**
+ * hdd_copy_vht_caps()- copy vht caps info from roam info to
+ * hdd station context.
+ * @hdd_sta_ctx: pointer to hdd station context
+ * @roam_info: pointer to roam info
+ *
+ * Return: None
+ */
+static void hdd_copy_ht_caps(hdd_station_ctx_t *hdd_sta_ctx,
+ tCsrRoamInfo *roam_info)
+{
+ tDot11fIEHTCaps *roam_ht_cap = &roam_info->ht_caps;
+ struct ieee80211_ht_cap *hdd_ht_cap = &hdd_sta_ctx->conn_info.ht_caps;
+ uint32_t i, temp_ht_cap;
+
+ vos_mem_zero(hdd_ht_cap, sizeof(struct ieee80211_ht_cap));
+
+ if (roam_ht_cap->advCodingCap)
+ hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_LDPC_CODING;
+ if (roam_ht_cap->supportedChannelWidthSet)
+ hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+ temp_ht_cap = roam_ht_cap->mimoPowerSave &
+ (IEEE80211_HT_CAP_SM_PS >> IEEE80211_HT_CAP_SM_PS_SHIFT);
+ if (temp_ht_cap)
+ hdd_ht_cap->cap_info |=
+ temp_ht_cap << IEEE80211_HT_CAP_SM_PS_SHIFT;
+ if (roam_ht_cap->greenField)
+ hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_GRN_FLD;
+ if (roam_ht_cap->shortGI20MHz)
+ hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_SGI_20;
+ if (roam_ht_cap->shortGI40MHz)
+ hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_SGI_40;
+ if (roam_ht_cap->txSTBC)
+ hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_TX_STBC;
+ temp_ht_cap = roam_ht_cap->rxSTBC & (IEEE80211_HT_CAP_RX_STBC >>
+ IEEE80211_HT_CAP_RX_STBC_SHIFT);
+ if (temp_ht_cap)
+ hdd_ht_cap->cap_info |=
+ temp_ht_cap << IEEE80211_HT_CAP_RX_STBC_SHIFT;
+ if (roam_ht_cap->delayedBA)
+ hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_DELAY_BA;
+ if (roam_ht_cap->maximalAMSDUsize)
+ hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_MAX_AMSDU;
+ if (roam_ht_cap->dsssCckMode40MHz)
+ hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_DSSSCCK40;
+ if (roam_ht_cap->psmp)
+ hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_RESERVED;
+ if (roam_ht_cap->stbcControlFrame)
+ hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_40MHZ_INTOLERANT;
+ if (roam_ht_cap->lsigTXOPProtection)
+ hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_LSIG_TXOP_PROT;
+
+
+ /* 802.11n HT capability AMPDU settings (for ampdu_params_info) */
+ if (roam_ht_cap->maxRxAMPDUFactor)
+ hdd_ht_cap->ampdu_params_info |=
+ IEEE80211_HT_AMPDU_PARM_FACTOR;
+ temp_ht_cap = roam_ht_cap->mpduDensity &
+ (IEEE80211_HT_AMPDU_PARM_DENSITY >>
+ IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
+ if (temp_ht_cap)
+ hdd_ht_cap->ampdu_params_info |=
+ temp_ht_cap << IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT;
+
+ /* 802.11n HT extended capabilities masks */
+ if (roam_ht_cap->pco)
+ hdd_ht_cap->extended_ht_cap_info |=
+ IEEE80211_HT_EXT_CAP_PCO;
+ temp_ht_cap = roam_ht_cap->transitionTime &
+ (IEEE80211_HT_EXT_CAP_PCO_TIME >>
+ IEEE80211_HT_EXT_CAP_PCO_TIME_SHIFT);
+ if (temp_ht_cap)
+ hdd_ht_cap->extended_ht_cap_info |=
+ temp_ht_cap << IEEE80211_HT_EXT_CAP_PCO_TIME_SHIFT;
+ temp_ht_cap = roam_ht_cap->mcsFeedback &
+ (IEEE80211_HT_EXT_CAP_MCS_FB >> IEEE80211_HT_EXT_CAP_MCS_FB_SHIFT);
+ if (temp_ht_cap)
+ hdd_ht_cap->extended_ht_cap_info |=
+ temp_ht_cap << IEEE80211_HT_EXT_CAP_MCS_FB_SHIFT;
+
+ /* tx_bf_cap_info capabilities */
+ if (roam_ht_cap->txBF)
+ hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_TX_BF;
+ if (roam_ht_cap->rxStaggeredSounding)
+ hdd_ht_cap->tx_BF_cap_info |=
+ TX_BF_CAP_INFO_RX_STAG_RED_SOUNDING;
+ if (roam_ht_cap->txStaggeredSounding)
+ hdd_ht_cap->tx_BF_cap_info |=
+ TX_BF_CAP_INFO_TX_STAG_RED_SOUNDING;
+ if (roam_ht_cap->rxZLF)
+ hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_RX_ZFL;
+ if (roam_ht_cap->txZLF)
+ hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_TX_ZFL;
+ if (roam_ht_cap->implicitTxBF)
+ hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_IMP_TX_BF;
+ temp_ht_cap = roam_ht_cap->calibration &
+ (TX_BF_CAP_INFO_CALIBRATION >> TX_BF_CAP_INFO_CALIBRATION_SHIFT);
+ if (temp_ht_cap)
+ hdd_ht_cap->tx_BF_cap_info |=
+ temp_ht_cap << TX_BF_CAP_INFO_CALIBRATION_SHIFT;
+ if (roam_ht_cap->explicitCSITxBF)
+ hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_EXP_CSIT_BF;
+ if (roam_ht_cap->explicitUncompressedSteeringMatrix)
+ hdd_ht_cap->tx_BF_cap_info |=
+ TX_BF_CAP_INFO_EXP_UNCOMP_STEER_MAT;
+ temp_ht_cap = roam_ht_cap->explicitBFCSIFeedback &
+ (TX_BF_CAP_INFO_EXP_BF_CSI_FB >>
+ TX_BF_CAP_INFO_EXP_BF_CSI_FB_SHIFT);
+ if (temp_ht_cap)
+ hdd_ht_cap->tx_BF_cap_info |=
+ temp_ht_cap << TX_BF_CAP_INFO_EXP_BF_CSI_FB_SHIFT;
+ temp_ht_cap =
+ roam_ht_cap->explicitUncompressedSteeringMatrixFeedback &
+ (TX_BF_CAP_INFO_EXP_UNCMP_STEER_MAT >>
+ TX_BF_CAP_INFO_EXP_UNCMP_STEER_MAT_SHIFT);
+ if (temp_ht_cap)
+ hdd_ht_cap->tx_BF_cap_info |=
+ temp_ht_cap <<
+ TX_BF_CAP_INFO_EXP_UNCMP_STEER_MAT_SHIFT;
+ temp_ht_cap =
+ roam_ht_cap->explicitCompressedSteeringMatrixFeedback &
+ (TX_BF_CAP_INFO_EXP_CMP_STEER_MAT_FB >>
+ TX_BF_CAP_INFO_EXP_CMP_STEER_MAT_FB_SHIFT);
+ if (temp_ht_cap)
+ hdd_ht_cap->tx_BF_cap_info |=
+ temp_ht_cap <<
+ TX_BF_CAP_INFO_EXP_CMP_STEER_MAT_FB_SHIFT;
+ temp_ht_cap = roam_ht_cap->csiNumBFAntennae &
+ (TX_BF_CAP_INFO_CSI_NUM_BF_ANT >>
+ TX_BF_CAP_INFO_CSI_NUM_BF_ANT_SHIFT);
+ if (temp_ht_cap)
+ hdd_ht_cap->tx_BF_cap_info |=
+ temp_ht_cap << TX_BF_CAP_INFO_CSI_NUM_BF_ANT_SHIFT;
+ temp_ht_cap = roam_ht_cap->uncompressedSteeringMatrixBFAntennae &
+ (TX_BF_CAP_INFO_UNCOMP_STEER_MAT_BF_ANT >>
+ TX_BF_CAP_INFO_UNCOMP_STEER_MAT_BF_ANT_SHIFT);
+ if (temp_ht_cap)
+ hdd_ht_cap->tx_BF_cap_info |=
+ temp_ht_cap <<
+ TX_BF_CAP_INFO_UNCOMP_STEER_MAT_BF_ANT_SHIFT;
+ temp_ht_cap = roam_ht_cap->compressedSteeringMatrixBFAntennae &
+ (TX_BF_CAP_INFO_COMP_STEER_MAT_BF_ANT >>
+ TX_BF_CAP_INFO_COMP_STEER_MAT_BF_ANT_SHIFT);
+ if (temp_ht_cap)
+ hdd_ht_cap->tx_BF_cap_info |=
+ temp_ht_cap <<
+ TX_BF_CAP_INFO_COMP_STEER_MAT_BF_ANT_SHIFT;
+
+ /* antenna selection */
+ if (roam_ht_cap->antennaSelection)
+ hdd_ht_cap->antenna_selection_info |= ANTENNA_SEL_INFO;
+ if (roam_ht_cap->explicitCSIFeedbackTx)
+ hdd_ht_cap->antenna_selection_info |=
+ ANTENNA_SEL_INFO_EXP_CSI_FB_TX;
+ if (roam_ht_cap->antennaIndicesFeedbackTx)
+ hdd_ht_cap->antenna_selection_info |=
+ ANTENNA_SEL_INFO_ANT_ID_FB_TX;
+ if (roam_ht_cap->explicitCSIFeedback)
+ hdd_ht_cap->antenna_selection_info |=
+ ANTENNA_SEL_INFO_EXP_CSI_FB;
+ if (roam_ht_cap->antennaIndicesFeedback)
+ hdd_ht_cap->antenna_selection_info |=
+ ANTENNA_SEL_INFO_ANT_ID_FB;
+ if (roam_ht_cap->rxAS)
+ hdd_ht_cap->antenna_selection_info |=
+ ANTENNA_SEL_INFO_RX_AS;
+ if (roam_ht_cap->txSoundingPPDUs)
+ hdd_ht_cap->antenna_selection_info |=
+ ANTENNA_SEL_INFO_TX_SOUNDING_PPDU;
+
+ /* mcs data rate */
+ for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; ++i)
+ hdd_ht_cap->mcs.rx_mask[i] =
+ roam_ht_cap->supportedMCSSet[i];
+ hdd_ht_cap->mcs.rx_highest =
+ ((short) (roam_ht_cap->supportedMCSSet[11]) << 8) |
+ ((short) (roam_ht_cap->supportedMCSSet[10]));
+ hdd_ht_cap->mcs.tx_params =
+ roam_ht_cap->supportedMCSSet[12];
+}
+
+
+#define VHT_CAP_MAX_MPDU_LENGTH_MASK 0x00000003
+#define VHT_CAP_SUPP_CHAN_WIDTH_MASK_SHIFT 2
+#define VHT_CAP_RXSTBC_MASK_SHIFT 8
+#define VHT_CAP_BEAMFORMEE_STS_SHIFT 13
+#define VHT_CAP_BEAMFORMEE_STS_MASK \
+ (0x0000e000 >> VHT_CAP_BEAMFORMEE_STS_SHIFT)
+#define VHT_CAP_SOUNDING_DIMENSIONS_SHIFT 16
+#define VHT_CAP_SOUNDING_DIMENSIONS_MASK \
+ (0x00070000 >> VHT_CAP_SOUNDING_DIMENSIONS_SHIFT)
+#define VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK_SHIFT 23
+#define VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK \
+ (0x03800000 >> VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK_SHIFT)
+#define VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB_SHIFT 26
+
+/**
+ * hdd_copy_ht_caps()- copy ht caps info from roam info to
+ * hdd station context.
+ * @hdd_sta_ctx: pointer to hdd station context
+ * @roam_info: pointer to roam info
+ *
+ * Return: None
+ */
+static void hdd_copy_vht_caps(hdd_station_ctx_t *hdd_sta_ctx,
+ tCsrRoamInfo *roam_info)
+{
+ tDot11fIEVHTCaps *roam_vht_cap = &roam_info->vht_caps;
+ struct ieee80211_vht_cap *hdd_vht_cap =
+ &hdd_sta_ctx->conn_info.vht_caps;
+ uint32_t temp_vht_cap;
+
+ vos_mem_zero(hdd_vht_cap, sizeof(struct ieee80211_vht_cap));
+
+ temp_vht_cap = roam_vht_cap->maxMPDULen & VHT_CAP_MAX_MPDU_LENGTH_MASK;
+ hdd_vht_cap->vht_cap_info |= temp_vht_cap;
+ temp_vht_cap = roam_vht_cap->supportedChannelWidthSet &
+ (IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK >>
+ VHT_CAP_SUPP_CHAN_WIDTH_MASK_SHIFT);
+ if (temp_vht_cap)
+ if (roam_vht_cap->supportedChannelWidthSet &
+ (IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ >>
+ VHT_CAP_SUPP_CHAN_WIDTH_MASK_SHIFT))
+ hdd_vht_cap->vht_cap_info |=
+ temp_vht_cap <<
+ IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
+ if (roam_vht_cap->supportedChannelWidthSet &
+ (IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ >>
+ VHT_CAP_SUPP_CHAN_WIDTH_MASK_SHIFT))
+ hdd_vht_cap->vht_cap_info |=
+ temp_vht_cap <<
+ IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
+ if (roam_vht_cap->ldpcCodingCap)
+ hdd_vht_cap->vht_cap_info |= IEEE80211_VHT_CAP_RXLDPC;
+ if (roam_vht_cap->shortGI80MHz)
+ hdd_vht_cap->vht_cap_info |= IEEE80211_VHT_CAP_SHORT_GI_80;
+ if (roam_vht_cap->shortGI160and80plus80MHz)
+ hdd_vht_cap->vht_cap_info |= IEEE80211_VHT_CAP_SHORT_GI_160;
+ if (roam_vht_cap->txSTBC)
+ hdd_vht_cap->vht_cap_info |= IEEE80211_VHT_CAP_TXSTBC;
+ temp_vht_cap = roam_vht_cap->rxSTBC & (IEEE80211_VHT_CAP_RXSTBC_MASK >>
+ VHT_CAP_RXSTBC_MASK_SHIFT);
+ if (temp_vht_cap)
+ hdd_vht_cap->vht_cap_info |=
+ temp_vht_cap << VHT_CAP_RXSTBC_MASK_SHIFT;
+ if (roam_vht_cap->suBeamFormerCap)
+ hdd_vht_cap->vht_cap_info |=
+ IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
+ if (roam_vht_cap->suBeamformeeCap)
+ hdd_vht_cap->vht_cap_info |=
+ IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
+ temp_vht_cap = roam_vht_cap->csnofBeamformerAntSup &
+ (VHT_CAP_BEAMFORMEE_STS_MASK);
+ if (temp_vht_cap)
+ hdd_vht_cap->vht_cap_info |=
+ temp_vht_cap << VHT_CAP_BEAMFORMEE_STS_SHIFT;
+ temp_vht_cap = roam_vht_cap->numSoundingDim &
+ (VHT_CAP_SOUNDING_DIMENSIONS_MASK);
+ if (temp_vht_cap)
+ hdd_vht_cap->vht_cap_info |=
+ temp_vht_cap << VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
+ if (roam_vht_cap->muBeamformerCap)
+ hdd_vht_cap->vht_cap_info |=
+ IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
+ if (roam_vht_cap->muBeamformeeCap)
+ hdd_vht_cap->vht_cap_info |=
+ IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
+ if (roam_vht_cap->vhtTXOPPS)
+ hdd_vht_cap->vht_cap_info |=
+ IEEE80211_VHT_CAP_VHT_TXOP_PS;
+ if (roam_vht_cap->htcVHTCap)
+ hdd_vht_cap->vht_cap_info |=
+ IEEE80211_VHT_CAP_HTC_VHT;
+ temp_vht_cap = roam_vht_cap->maxAMPDULenExp &
+ (VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK);
+ if (temp_vht_cap)
+ hdd_vht_cap->vht_cap_info |=
+ temp_vht_cap <<
+ VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK_SHIFT;
+ temp_vht_cap = roam_vht_cap->vhtLinkAdaptCap &
+ (IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB >>
+ VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB_SHIFT);
+ if (temp_vht_cap)
+ hdd_vht_cap->vht_cap_info |= temp_vht_cap <<
+ VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB_SHIFT;
+ if (roam_vht_cap->rxAntPattern)
+ hdd_vht_cap->vht_cap_info |=
+ IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN;
+ if (roam_vht_cap->txAntPattern)
+ hdd_vht_cap->vht_cap_info |=
+ IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;
+ hdd_vht_cap->supp_mcs.rx_mcs_map = roam_vht_cap->rxMCSMap;
+ hdd_vht_cap->supp_mcs.rx_highest =
+ ((uint16_t)roam_vht_cap->rxHighSupDataRate);
+ hdd_vht_cap->supp_mcs.tx_mcs_map = roam_vht_cap->txMCSMap;
+ hdd_vht_cap->supp_mcs.tx_highest =
+ ((uint16_t)roam_vht_cap->txSupDataRate);
+}
+
+/* ht param */
+#define HT_PARAM_CONTROLLED_ACCESS_ONLY 0x10
+#define HT_PARAM_SERVICE_INT_GRAN 0xe0
+#define HT_PARAM_SERVICE_INT_GRAN_SHIFT 5
+
+/* operatinon mode */
+#define HT_OP_MODE_TX_BURST_LIMIT 0x0008
+
+/* stbc_param */
+#define HT_STBC_PARAM_MCS 0x007f
+
+/**
+ * hdd_copy_ht_operation()- copy HT operation element from roam info to
+ * hdd station context.
+ * @hdd_sta_ctx: pointer to hdd station context
+ * @roam_info: pointer to roam info
+ *
+ * Return: None
+ */
+static void hdd_copy_ht_operation(hdd_station_ctx_t *hdd_sta_ctx,
+ tCsrRoamInfo *roam_info)
+{
+ tDot11fIEHTInfo *roam_ht_ops = &roam_info->ht_operation;
+ struct ieee80211_ht_operation *hdd_ht_ops =
+ &hdd_sta_ctx->conn_info.ht_operation;
+ uint32_t i, temp_ht_ops;
+
+ vos_mem_zero(hdd_ht_ops, sizeof(struct ieee80211_ht_operation));
+
+ hdd_ht_ops->primary_chan = roam_ht_ops->primaryChannel;
+
+ /* HT_PARAMS */
+ temp_ht_ops = roam_ht_ops->secondaryChannelOffset &
+ IEEE80211_HT_PARAM_CHA_SEC_OFFSET;
+ if (temp_ht_ops)
+ hdd_ht_ops->ht_param |= temp_ht_ops;
+ else
+ hdd_ht_ops->ht_param = IEEE80211_HT_PARAM_CHA_SEC_NONE;
+ if (roam_ht_ops->recommendedTxWidthSet)
+ hdd_ht_ops->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY;
+ if (roam_ht_ops->rifsMode)
+ hdd_ht_ops->ht_param |= IEEE80211_HT_PARAM_RIFS_MODE;
+ if (roam_ht_ops->controlledAccessOnly)
+ hdd_ht_ops->ht_param |= HT_PARAM_CONTROLLED_ACCESS_ONLY;
+ temp_ht_ops = roam_ht_ops->serviceIntervalGranularity &
+ (HT_PARAM_SERVICE_INT_GRAN >> HT_PARAM_SERVICE_INT_GRAN_SHIFT);
+ if (temp_ht_ops)
+ hdd_ht_ops->ht_param |= temp_ht_ops <<
+ HT_PARAM_SERVICE_INT_GRAN_SHIFT;
+
+ /* operation mode */
+ temp_ht_ops = roam_ht_ops->opMode &
+ IEEE80211_HT_OP_MODE_PROTECTION;
+ switch (temp_ht_ops) {
+ case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER:
+ hdd_ht_ops->operation_mode |=
+ IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER;
+ break;
+ case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
+ hdd_ht_ops->operation_mode |=
+ IEEE80211_HT_OP_MODE_PROTECTION_20MHZ;
+ break;
+ case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
+ hdd_ht_ops->operation_mode |=
+ IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED;
+ break;
+ case IEEE80211_HT_OP_MODE_PROTECTION_NONE:
+ default:
+ hdd_ht_ops->operation_mode |=
+ IEEE80211_HT_OP_MODE_PROTECTION_NONE;
+ }
+ if (roam_ht_ops->nonGFDevicesPresent)
+ hdd_ht_ops->operation_mode |=
+ IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT;
+ if (roam_ht_ops->transmitBurstLimit)
+ hdd_ht_ops->operation_mode |=
+ HT_OP_MODE_TX_BURST_LIMIT;
+ if (roam_ht_ops->obssNonHTStaPresent)
+ hdd_ht_ops->operation_mode |=
+ IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT;
+
+ /* stbc_param */
+ temp_ht_ops = roam_ht_ops->basicSTBCMCS &
+ HT_STBC_PARAM_MCS;
+ if (temp_ht_ops)
+ hdd_ht_ops->stbc_param |= temp_ht_ops;
+ if (roam_ht_ops->dualCTSProtection)
+ hdd_ht_ops->stbc_param |=
+ IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT;
+ if (roam_ht_ops->secondaryBeacon)
+ hdd_ht_ops->stbc_param |=
+ IEEE80211_HT_STBC_PARAM_STBC_BEACON;
+ if (roam_ht_ops->lsigTXOPProtectionFullSupport)
+ hdd_ht_ops->stbc_param |=
+ IEEE80211_HT_STBC_PARAM_LSIG_TXOP_FULLPROT;
+ if (roam_ht_ops->pcoActive)
+ hdd_ht_ops->stbc_param |=
+ IEEE80211_HT_STBC_PARAM_PCO_ACTIVE;
+ if (roam_ht_ops->pcoPhase)
+ hdd_ht_ops->stbc_param |=
+ IEEE80211_HT_STBC_PARAM_PCO_PHASE;
+
+ /* basic MCs set */
+ for (i = 0; i < 16; ++i)
+ hdd_ht_ops->basic_set[i] =
+ roam_ht_ops->basicMCSSet[i];
+}
+
+/**
+ * hdd_copy_vht_operation()- copy VHT operations element from roam info to
+ * hdd station context.
+ * @hdd_sta_ctx: pointer to hdd station context
+ * @roam_info: pointer to roam info
+ *
+ * Return: None
+ */
+static void hdd_copy_vht_operation(hdd_station_ctx_t *hdd_sta_ctx,
+ tCsrRoamInfo *roam_info)
+{
+ tDot11fIEVHTOperation *roam_vht_ops = &roam_info->vht_operation;
+ struct ieee80211_vht_operation *hdd_vht_ops =
+ &hdd_sta_ctx->conn_info.vht_operation;
+
+ vos_mem_zero(hdd_vht_ops, sizeof(struct ieee80211_vht_operation));
+
+ hdd_vht_ops->chan_width = roam_vht_ops->chanWidth;
+ hdd_vht_ops->center_freq_seg1_idx = roam_vht_ops->chanCenterFreqSeg1;
+ hdd_vht_ops->center_freq_seg2_idx = roam_vht_ops->chanCenterFreqSeg2;
+ hdd_vht_ops->basic_mcs_set = roam_vht_ops->basicMCSSet;
+}
+
+
+/**
+ * hdd_save_bss_info() - save connection info in hdd sta ctx
+ * @adapter: Pointer to adapter
+ * @roam_info: pointer to roam info
+ *
+ * Return: None
+ */
+static void hdd_save_bss_info(hdd_adapter_t *adapter,
+ tCsrRoamInfo *roam_info)
+{
+ hdd_station_ctx_t *hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+ hdd_sta_ctx->conn_info.freq = vos_chan_to_freq(
+ hdd_sta_ctx->conn_info.operationChannel);
+ if (roam_info->vht_caps.present) {
+ hdd_sta_ctx->conn_info.conn_flag.vht_present = true;
+ hdd_copy_vht_caps(hdd_sta_ctx, roam_info);
+ } else {
+ hdd_sta_ctx->conn_info.conn_flag.vht_present = false;
+ }
+ if (roam_info->ht_caps.present) {
+ hdd_sta_ctx->conn_info.conn_flag.ht_present = true;
+ hdd_copy_ht_caps(hdd_sta_ctx, roam_info);
+ } else {
+ hdd_sta_ctx->conn_info.conn_flag.ht_present = false;
+ }
+ if (roam_info->reassoc)
+ hdd_sta_ctx->conn_info.roam_count++;
+ if (roam_info->hs20vendor_ie.present) {
+ hdd_sta_ctx->conn_info.conn_flag.hs20_present = true;
+ vos_mem_copy(&hdd_sta_ctx->conn_info.hs20vendor_ie,
+ &roam_info->hs20vendor_ie,
+ sizeof(roam_info->hs20vendor_ie));
+ } else {
+ hdd_sta_ctx->conn_info.conn_flag.hs20_present = false;
+ }
+ if (roam_info->ht_operation.present) {
+ hdd_sta_ctx->conn_info.conn_flag.ht_op_present = true;
+ hdd_copy_ht_operation(hdd_sta_ctx, roam_info);
+ } else {
+ hdd_sta_ctx->conn_info.conn_flag.ht_op_present = false;
+ }
+ if (roam_info->vht_operation.present) {
+ hdd_sta_ctx->conn_info.conn_flag.vht_op_present = true;
+ hdd_copy_vht_operation(hdd_sta_ctx, roam_info);
+ } else {
+ hdd_sta_ctx->conn_info.conn_flag.vht_op_present = false;
+ }
+}
+
void hdd_connSaveConnectInfo( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, eCsrRoamBssType eBssType )
{
hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
@@ -329,6 +810,7 @@ void hdd_connSaveConnectInfo( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
pHddStaCtx->conn_info.rate_flags = pRoamInfo->maxRateFlags;
}
+ hdd_save_bss_info(pAdapter, pRoamInfo);
}
// save the connected BssType
@@ -982,6 +1464,53 @@ static VOS_STATUS hdd_roamDeregisterSTA( hdd_adapter_t *pAdapter, tANI_U8 staId
return( vosStatus );
}
+/**
+ * hdd_print_bss_info() - print bss info
+ * @hdd_sta_ctx: pointer to hdd station context
+ *
+ * Return: None
+ */
+void hdd_print_bss_info(hdd_station_ctx_t *hdd_sta_ctx)
+{
+ uint32_t *cap_info;
+
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"WIFI DATA LOGGER");
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"channel: %d",
+ hdd_sta_ctx->conn_info.freq);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"dot11mode: %d",
+ hdd_sta_ctx->conn_info.dot11Mode);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"AKM: %d",
+ hdd_sta_ctx->conn_info.authType);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"ssid: %.*s",
+ hdd_sta_ctx->conn_info.SSID.SSID.length,
+ hdd_sta_ctx->conn_info.SSID.SSID.ssId);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"roam count: %d",
+ hdd_sta_ctx->conn_info.roam_count);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"ant_info: %d",
+ hdd_sta_ctx->conn_info.txrate.nss);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"datarate legacy %d",
+ hdd_sta_ctx->conn_info.txrate.legacy);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"datarate mcs: %d",
+ hdd_sta_ctx->conn_info.txrate.mcs);
+ if (hdd_sta_ctx->conn_info.conn_flag.ht_present) {
+ cap_info = (uint32_t *)&hdd_sta_ctx->conn_info.ht_caps;
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"ht caps: %x",
+ *cap_info);
+ }
+ if (hdd_sta_ctx->conn_info.conn_flag.vht_present) {
+ cap_info = (uint32_t *)&hdd_sta_ctx->conn_info.vht_caps;
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"vht caps: %x",
+ *cap_info);
+ }
+ if (hdd_sta_ctx->conn_info.conn_flag.hs20_present)
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"hs20 info: %x",
+ hdd_sta_ctx->conn_info.hs20vendor_ie.release_num);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"signal: %d",
+ hdd_sta_ctx->conn_info.signal);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"noise: %d",
+ hdd_sta_ctx->conn_info.noise);
+}
+
static eHalStatus hdd_DisConnectHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
tANI_U32 roamId, eRoamCmdStatus roamStatus,
@@ -1285,6 +1814,7 @@ static eHalStatus hdd_DisConnectHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *
//Unblock anyone waiting for disconnect to complete
complete(&pAdapter->disconnect_comp_var);
+ hdd_print_bss_info(pHddStaCtx);
return( status );
}
@@ -1976,12 +2506,11 @@ static eHalStatus hdd_AssociationCompletionHandler( hdd_adapter_t *pAdapter, tCs
"wlan: connection failed with " MAC_ADDRESS_STR " result:%d and Status:%d",
MAC_ADDR_ARRAY(pWextState->req_bssId),
roamResult, roamStatus);
-
- if (( eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus) ||
- ((roamResult != eCSR_ROAM_RESULT_ASSOCIATED) &&
- (eCSR_ROAM_ASSOCIATION_COMPLETION == roamStatus)))
+ if (!pHddStaCtx->get_mgmt_log_sent) {
+ pHddStaCtx->get_mgmt_log_sent = TRUE;
wlan_hdd_get_frame_logs(pAdapter,
WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
+ }
if ((eCSR_ROAM_RESULT_SCAN_FOR_SSID_FAILURE == roamResult) ||
(pRoamInfo &&
@@ -2055,20 +2584,23 @@ static eHalStatus hdd_AssociationCompletionHandler( hdd_adapter_t *pAdapter, tCs
wlan_hdd_tdls_reenable(pHddCtx);
}
- if (pRoamInfo)
+ if (pRoamInfo) {
hddLog(VOS_TRACE_LEVEL_ERROR,
"%s: send connect failure to nl80211:"
" for bssid " MAC_ADDRESS_STR
" result:%d and Status:%d reasonCode %d" ,
__func__, MAC_ADDR_ARRAY(pRoamInfo->bssid),
roamResult, roamStatus, pRoamInfo->reasonCode);
- else
+ pHddStaCtx->conn_info.assoc_status_code =
+ pRoamInfo->statusCode;
+ } else {
hddLog(VOS_TRACE_LEVEL_ERROR,
"%s: connect failed:"
" for bssid " MAC_ADDRESS_STR
" result:%d and Status:%d" ,
__func__, MAC_ADDR_ARRAY(pWextState->req_bssId),
roamResult, roamStatus);
+ }
/* inform association failure event to nl80211 */
if ( eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL == roamResult )
@@ -2131,6 +2663,10 @@ static eHalStatus hdd_AssociationCompletionHandler( hdd_adapter_t *pAdapter, tCs
"and STA channel is %d", pHostapdAdapter->sessionCtx.ap.operatingChannel,
(int)pRoamInfo->pBssDesc->channelId);
hdd_hostapd_stop(pHostapdAdapter->dev);
+ if (pHddCtx->cfg_ini->enable_sap_auth_offload)
+ hdd_force_scc_restart_sap(pHostapdAdapter,
+ pHddCtx, (int)pRoamInfo->pBssDesc->channelId);
+
}
}
}
@@ -4097,6 +4633,19 @@ int hdd_set_csr_auth_type ( hdd_adapter_t *pAdapter, eCsrAuthType RSNAuthType)
return 0;
}
+/**
+ * hdd_rx_fwd_eapol() - forward cached eapol frames
+ * @vosContext : pointer to vos global context
+ * @pVosPacket: pointer to vos packet
+ *
+ * Return: None
+ *
+ */
+void hdd_assoc_registerFwdEapolCB(void *pContext)
+{
+ WLANTL_RegisterFwdEapol(pContext, hdd_rx_fwd_eapol);
+}
+
/**---------------------------------------------------------------------------
\brief __iw_set_essid() -
@@ -4121,7 +4670,6 @@ int __iw_set_essid(struct net_device *dev,
hdd_context_t *pHddCtx;
v_U32_t roamId;
tCsrRoamProfile *pRoamProfile;
- eMib_dot11DesiredBssType connectedBssType;
eCsrAuthType RSNAuthType;
tHalHandle hHal;
hdd_station_ctx_t *pHddStaCtx;
@@ -4171,25 +4719,14 @@ int __iw_set_essid(struct net_device *dev,
if( SIR_MAC_MAX_SSID_LENGTH < wrqu->essid.length )
return -EINVAL;
pRoamProfile = &pWextState->roamProfile;
- if (pRoamProfile)
- {
- if ( hdd_connGetConnectedBssType( pHddStaCtx, &connectedBssType ) ||
- ( eMib_dot11DesiredBssType_independent == pHddStaCtx->conn_info.connDot11DesiredBssType ))
- {
- VOS_STATUS vosStatus;
- // need to issue a disconnect to CSR.
- INIT_COMPLETION(pAdapter->disconnect_comp_var);
- vosStatus = sme_RoamDisconnect( hHal, pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED );
-
- if(VOS_STATUS_SUCCESS == vosStatus)
- wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
- msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
- }
- }
- /** wpa_supplicant 0.8.x, wext driver uses */
- else
+
+ /*Try disconnecting if already in connected state*/
+ status = wlan_hdd_try_disconnect(pAdapter);
+ if (0 > status)
{
- return -EINVAL;
+ hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
+ " connection"));
+ return -EALREADY;
}
/** wpa_supplicant 0.8.x, wext driver uses */
/** when cfg80211 defined, wpa_supplicant wext driver uses
diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg.c
index 89270a3ce4a..7272ed0d912 100644
--- a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg.c
+++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg.c
@@ -487,6 +487,13 @@ REG_TABLE_ENTRY g_registry_table[] =
CFG_CHANNEL_BONDING_MODE_MIN,
CFG_CHANNEL_BONDING_MODE_MAX),
+ REG_VARIABLE(CFG_OVERRIDE_HT40_20_24GHZ_NAME, WLAN_PARAM_Integer,
+ hdd_config_t, override_ht20_40_24g,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_OVERRIDE_HT40_20_24GHZ_DEFAULT,
+ CFG_OVERRIDE_HT40_20_24GHZ_MIN,
+ CFG_OVERRIDE_HT40_20_24GHZ_MAX),
+
REG_VARIABLE( CFG_CHANNEL_BONDING_MODE_5GHZ_NAME, WLAN_PARAM_Integer,
hdd_config_t, nChannelBondingMode5GHz,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK,
@@ -1955,6 +1962,14 @@ REG_TABLE_ENTRY g_registry_table[] =
CFG_NEIGHBOR_INITIAL_FORCED_ROAM_TO_5GH_ENABLE_MIN,
CFG_NEIGHBOR_INITIAL_FORCED_ROAM_TO_5GH_ENABLE_MAX),
+ REG_VARIABLE(CFG_NEIGHBOR_WEAK_ZONE_RSSI_THRESHOLD_FOR_ROAM_NAME,
+ WLAN_PARAM_Integer,
+ hdd_config_t, nWeakZoneRssiThresholdForRoam,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_NEIGHBOR_WEAK_ZONE_RSSI_THRESHOLD_FOR_ROAM_DEFAULT,
+ CFG_NEIGHBOR_WEAK_ZONE_RSSI_THRESHOLD_FOR_ROAM_MIN,
+ CFG_NEIGHBOR_WEAK_ZONE_RSSI_THRESHOLD_FOR_ROAM_MAX),
+
#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */
REG_VARIABLE( CFG_QOS_WMM_BURST_SIZE_DEFN_NAME , WLAN_PARAM_Integer,
@@ -2227,13 +2242,6 @@ REG_TABLE_ENTRY g_registry_table[] =
CFG_BCN_EARLY_TERM_WAKE_MIN,
CFG_BCN_EARLY_TERM_WAKE_MAX ),
- REG_VARIABLE( CFG_AP_DATA_AVAIL_POLL_PERIOD_NAME, WLAN_PARAM_Integer,
- hdd_config_t, apDataAvailPollPeriodInMs,
- VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
- CFG_AP_DATA_AVAIL_POLL_PERIOD_DEFAULT,
- CFG_AP_DATA_AVAIL_POLL_PERIOD_MIN,
- CFG_AP_DATA_AVAIL_POLL_PERIOD_MAX ),
-
REG_VARIABLE( CFG_ENABLE_CLOSE_LOOP_NAME, WLAN_PARAM_Integer,
hdd_config_t, enableCloseLoop,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
@@ -2884,6 +2892,15 @@ REG_VARIABLE( CFG_EXTSCAN_ENABLE, WLAN_PARAM_Integer,
CFG_PER_ROAM_BAD_RSSI_MAX),
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+ REG_VARIABLE(CFG_ENABLE_LFR_MBB, WLAN_PARAM_Integer,
+ hdd_config_t, enable_lfr_mbb,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_ENABLE_LFR_MBB_DEFAULT,
+ CFG_ENABLE_LFR_MBB_MIN,
+ CFG_ENABLE_LFR_MBB_MAX ),
+#endif
+
REG_VARIABLE( CFG_ENABLE_ADAPT_RX_DRAIN_NAME, WLAN_PARAM_Integer,
hdd_config_t, fEnableAdaptRxDrain,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK ,
@@ -3497,6 +3514,13 @@ REG_VARIABLE( CFG_EXTSCAN_ENABLE, WLAN_PARAM_Integer,
CFG_BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN_MIN,
CFG_BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN_MAX ),
+ REG_VARIABLE( CFG_BTC_DISABLE_WLAN_LINK_CRITICAL , WLAN_PARAM_Integer,
+ hdd_config_t, btc_disable_wlan_link_critical,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_DEFAULT,
+ CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_MIN,
+ CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_MAX ),
+
REG_VARIABLE( CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN , WLAN_PARAM_Integer,
hdd_config_t, btcStaticOppWlanIdleBtLen,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
@@ -3624,6 +3648,7 @@ REG_VARIABLE( CFG_EXTSCAN_ENABLE, WLAN_PARAM_Integer,
CFG_SAR_BOFFSET_SET_CORRECTION_MIN,
CFG_SAR_BOFFSET_SET_CORRECTION_MAX),
+
REG_VARIABLE(CFG_ENABLE_EDCA_INI_NAME, WLAN_PARAM_Integer,
hdd_config_t, enable_edca_params,
VAR_FLAGS_OPTIONAL |
@@ -3755,6 +3780,162 @@ REG_VARIABLE( CFG_EXTSCAN_ENABLE, WLAN_PARAM_Integer,
CFG_DISABLE_SCAN_DURING_SCO_DEFAULT,
CFG_DISABLE_SCAN_DURING_SCO_MIN,
CFG_DISABLE_SCAN_DURING_SCO_MAX ),
+#ifdef SAP_AUTH_OFFLOAD
+ REG_VARIABLE(CFG_ENABLE_SAP_AUTH_OFL_NAME, WLAN_PARAM_Integer,
+ hdd_config_t, enable_sap_auth_offload,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_ENABLE_SAP_AUTH_OFL_DEFAULT,
+ CFG_ENABLE_SAP_AUTH_OFL_MIN,
+ CFG_ENABLE_SAP_AUTH_OFL_MAX ),
+
+ REG_VARIABLE(CFG_SAP_AUTH_OFL_SECURITY_TYPE_NAME, WLAN_PARAM_Integer,
+ hdd_config_t, sap_auth_offload_sec_type,
+ VAR_FLAGS_OPTIONAL | CFG_SAP_AUTH_OFL_SECURITY_TYPE_DEFAULT,
+ CFG_SAP_AUTH_OFL_SECURITY_TYPE_DEFAULT,
+ CFG_SAP_AUTH_OFL_SECURITY_TYPE_MIN,
+ CFG_SAP_AUTH_OFL_SECURITY_TYPE_MAX ),
+
+ REG_VARIABLE_STRING(CFG_SAP_AUTH_OFL_KEY_NAME, WLAN_PARAM_String,
+ hdd_config_t, sap_auth_offload_key,
+ VAR_FLAGS_OPTIONAL,
+ (void *) CFG_SAP_AUTH_OFL_KEY_DEFAULT ),
+#endif
+#ifdef DHCP_SERVER_OFFLOAD
+ REG_VARIABLE(CFG_DHCP_SERVER_OFFLOAD_SUPPORT_NAME, WLAN_PARAM_Integer,
+ hdd_config_t, enable_dhcp_srv_offload,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_DHCP_SERVER_OFFLOAD_SUPPORT_DEFAULT,
+ CFG_DHCP_SERVER_OFFLOAD_SUPPORT_MIN,
+ CFG_DHCP_SERVER_OFFLOAD_SUPPORT_MAX),
+
+ REG_VARIABLE(CFG_DHCP_SERVER_OFFLOAD_NUM_CLIENT_NAME, WLAN_PARAM_Integer,
+ hdd_config_t, dhcp_max_num_clients,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_DHCP_SERVER_OFFLOAD_NUM_CLIENT_DEFAULT,
+ CFG_DHCP_SERVER_OFFLOAD_NUM_CLIENT_MIN,
+ CFG_DHCP_SERVER_OFFLOAD_NUM_CLIENT_MAX),
+
+ REG_VARIABLE_STRING(CFG_DHCP_SERVER_IP_NAME, WLAN_PARAM_String,
+ hdd_config_t, dhcp_srv_ip,
+ VAR_FLAGS_OPTIONAL,
+ (void *) CFG_DHCP_SERVER_IP_DEFAULT),
+
+ REG_VARIABLE(CFG_DHCP_SERVER_OFFLOAD_START_LSB_NAME, WLAN_PARAM_Integer,
+ hdd_config_t, dhcp_start_lsb,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_DHCP_SERVER_OFFLOAD_START_LSB_DEFAULT,
+ CFG_DHCP_SERVER_OFFLOAD_START_LSB_MIN,
+ CFG_DHCP_SERVER_OFFLOAD_START_LSB_MAX),
+#endif /* DHCP_SERVER_OFFLOAD */
+ REG_VARIABLE(CFG_MAX_SCHED_SCAN_PLAN_INT_NAME, WLAN_PARAM_Integer,
+ hdd_config_t, max_sched_scan_plan_interval,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_MAX_SCHED_SCAN_PLAN_INT_DEFAULT,
+ CFG_MAX_SCHED_SCAN_PLAN_INT_MIN,
+ CFG_MAX_SCHED_SCAN_PLAN_INT_MAX),
+
+ REG_VARIABLE(CFG_MAX_SCHED_SCAN_PLAN_ITRNS_NAME, WLAN_PARAM_Integer,
+ hdd_config_t, max_sched_scan_plan_iterations,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_MAX_SCHED_SCAN_PLAN_ITRNS_DEFAULT,
+ CFG_MAX_SCHED_SCAN_PLAN_ITRNS_MIN,
+ CFG_MAX_SCHED_SCAN_PLAN_ITRNS_MAX),
+
+#ifdef MDNS_OFFLOAD
+ REG_VARIABLE( CFG_MDNS_OFFLOAD_SUPPORT_NAME, WLAN_PARAM_Integer,
+ hdd_config_t, enable_mdns_offload,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_MDNS_OFFLOAD_SUPPORT_DEFAULT,
+ CFG_MDNS_OFFLOAD_SUPPORT_MIN,
+ CFG_MDNS_OFFLOAD_SUPPORT_MAX ),
+
+ REG_VARIABLE_STRING( CFG_MDNS_FQDN_NAME, WLAN_PARAM_String,
+ hdd_config_t, mdns_fqdn,
+ VAR_FLAGS_OPTIONAL,
+ (void *) CFG_MDNS_FQDN_DEFAULT ),
+
+ REG_VARIABLE_STRING( CFG_MDNS_UNIQUE_FQDN_NAME, WLAN_PARAM_String,
+ hdd_config_t, mdns_uniquefqdn,
+ VAR_FLAGS_OPTIONAL,
+ (void *) CFG_MDNS_UNIQUE_FQDN_DEFAULT ),
+
+ REG_VARIABLE_STRING( CFG_MDNS_RESPONSE_TYPE_A_NAME, WLAN_PARAM_String,
+ hdd_config_t, mdns_resp_type_a,
+ VAR_FLAGS_OPTIONAL,
+ (void *) CFG_MDNS_RESPONSE_TYPE_A_DEFAULT ),
+
+ REG_VARIABLE( CFG_MDNS_RESPONSE_TYPE_A_IPV4_NAME, WLAN_PARAM_HexInteger,
+ hdd_config_t, mdns_resp_type_a_ipv4,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_MDNS_RESPONSE_TYPE_A_IPV4_DEFAULT,
+ CFG_MDNS_RESPONSE_TYPE_A_IPV4_MIN,
+ CFG_MDNS_RESPONSE_TYPE_A_IPV4_MAX ),
+
+ REG_VARIABLE_STRING( CFG_MDNS_RESPONSE_TYPE_TXT_NAME, WLAN_PARAM_String,
+ hdd_config_t, mdns_resp_type_txt,
+ VAR_FLAGS_OPTIONAL,
+ (void *) CFG_MDNS_RESPONSE_TYPE_TXT_DEFAULT ),
+
+ REG_VARIABLE_STRING( CFG_MDNS_RESPONSE_TYPE_TXT_CNT_NAME, WLAN_PARAM_String,
+ hdd_config_t, mdns_resp_type_txt_content,
+ VAR_FLAGS_OPTIONAL,
+ (void *) CFG_MDNS_RESPONSE_TYPE_TXT_CNT_DEFAULT ),
+
+ REG_VARIABLE_STRING( CFG_MDNS_RESPONSE_TYPE_PTR_NAME, WLAN_PARAM_String,
+ hdd_config_t, mdns_resp_type_ptr,
+ VAR_FLAGS_OPTIONAL,
+ (void *) CFG_MDNS_RESPONSE_TYPE_PTR_DEFAULT ),
+
+ REG_VARIABLE_STRING( CFG_MDNS_RESPONSE_TYPE_PTR_DN_NAME, WLAN_PARAM_String,
+ hdd_config_t, mdns_resp_type_ptr_dname,
+ VAR_FLAGS_OPTIONAL,
+ (void *) CFG_MDNS_RESPONSE_TYPE_PTR_DN_DEFAULT ),
+
+ REG_VARIABLE_STRING( CFG_MDNS_RESPONSE_TYPE_SRV_NAME, WLAN_PARAM_String,
+ hdd_config_t, mdns_resp_type_srv,
+ VAR_FLAGS_OPTIONAL,
+ (void *) CFG_MDNS_RESPONSE_TYPE_SRV_DEFAULT ),
+
+ REG_VARIABLE( CFG_MDNS_RESPONSE_TYPE_SRV_PRIORITY_NAME, WLAN_PARAM_Integer,
+ hdd_config_t, mdns_resp_type_srv_priority,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_MDNS_RESPONSE_TYPE_SRV_PRIORITY_DEFAULT,
+ CFG_MDNS_RESPONSE_TYPE_SRV_PRIORITY_MIN,
+ CFG_MDNS_RESPONSE_TYPE_SRV_PRIORITY_MAX ),
+
+ REG_VARIABLE( CFG_MDNS_RESPONSE_TYPE_SRV_WEIGHT_NAME, WLAN_PARAM_Integer,
+ hdd_config_t, mdns_resp_type_srv_weight,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_MDNS_RESPONSE_TYPE_SRV_WEIGHT_DEFAULT,
+ CFG_MDNS_RESPONSE_TYPE_SRV_WEIGHT_MIN,
+ CFG_MDNS_RESPONSE_TYPE_SRV_WEIGHT_MAX ),
+
+ REG_VARIABLE( CFG_MDNS_RESPONSE_TYPE_SRV_PORT_NAME, WLAN_PARAM_Integer,
+ hdd_config_t, mdns_resp_type_srv_port,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_MDNS_RESPONSE_TYPE_SRV_PORT_DEFAULT,
+ CFG_MDNS_RESPONSE_TYPE_SRV_PORT_MIN,
+ CFG_MDNS_RESPONSE_TYPE_SRV_PORT_MAX ),
+
+ REG_VARIABLE_STRING( CFG_MDNS_RESPONSE_TYPE_SRV_TGT_NAME, WLAN_PARAM_String,
+ hdd_config_t, mdns_resp_type_srv_target,
+ VAR_FLAGS_OPTIONAL,
+ (void *) CFG_MDNS_RESPONSE_TYPE_SRV_TGT_DEFAULT ),
+#endif /* MDNS_OFFLOAD */
+
+ REG_VARIABLE( CFG_STA_AUTH_RETRIES_FOR_CODE17_NAME, WLAN_PARAM_Integer,
+ hdd_config_t, sta_auth_retries_for_code17,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_STA_AUTH_RETRIES_FOR_CODE17_DEFAULT,
+ CFG_STA_AUTH_RETRIES_FOR_CODE17_MIN,
+ CFG_STA_AUTH_RETRIES_FOR_CODE17_MAX ),
+
+ REG_VARIABLE( CFG_TRIGGER_NULLFRAME_BEFORE_HB_NAME, WLAN_PARAM_Integer,
+ hdd_config_t, trigger_nullframe_before_hb,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_TRIGGER_NULLFRAME_BEFORE_HB_DEFAULT,
+ CFG_TRIGGER_NULLFRAME_BEFORE_HB_MIN,
+ CFG_TRIGGER_NULLFRAME_BEFORE_HB_MAX ),
};
/*
@@ -4016,6 +4197,8 @@ static void print_hdd_cfg(hdd_context_t *pHddCtx)
VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gApAutoChannelSelection] value = [%u]",pHddCtx->cfg_ini->apAutoChannelSelection);
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [ChannelBondingMode] Value = [%u]",pHddCtx->cfg_ini->nChannelBondingMode24GHz);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [%s] Value = [%u] ",
+ CFG_OVERRIDE_HT40_20_24GHZ_NAME, pHddCtx->cfg_ini->override_ht20_40_24g);
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [ChannelBondingMode] Value = [%u]",pHddCtx->cfg_ini->nChannelBondingMode5GHz);
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [dot11Mode] Value = [%u]",pHddCtx->cfg_ini->dot11Mode);
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [WmmMode] Value = [%u] ",pHddCtx->cfg_ini->WmmMode);
@@ -4102,6 +4285,7 @@ static void print_hdd_cfg(hdd_context_t *pHddCtx)
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [nNeighborScanResultsRefreshPeriod] Value = [%u] ",pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod);
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [nEmptyScanRefreshPeriod] Value = [%u] ",pHddCtx->cfg_ini->nEmptyScanRefreshPeriod);
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [nNeighborInitialForcedRoamTo5GhEnable] Value = [%u] ",pHddCtx->cfg_ini->nNeighborInitialForcedRoamTo5GhEnable);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [nWeakZoneRssiThresholdForRoam] Value = [%u] ",pHddCtx->cfg_ini->nWeakZoneRssiThresholdForRoam);
#endif
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [burstSizeDefinition] Value = [0x%x] ",pHddCtx->cfg_ini->burstSizeDefinition);
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [tsInfoAckPolicy] Value = [0x%x] ",pHddCtx->cfg_ini->tsInfoAckPolicy);
@@ -4125,7 +4309,6 @@ static void print_hdd_cfg(hdd_context_t *pHddCtx)
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [maxListenInterval] Value = [%u] ",pHddCtx->cfg_ini->nTeleBcnMaxListenInterval);
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [maxLiNumIdleBeacons] Value = [%u] ",pHddCtx->cfg_ini->nTeleBcnMaxLiNumIdleBeacons);
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [bcnEarlyTermWakeInterval] Value = [%u] ",pHddCtx->cfg_ini->bcnEarlyTermWakeInterval);
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gApDataAvailPollInterVal] Value = [%u] ",pHddCtx->cfg_ini->apDataAvailPollPeriodInMs);
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableBypass11d] Value = [%u] ",pHddCtx->cfg_ini->enableBypass11d);
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableDFSChnlScan] Value = [%u] ",pHddCtx->cfg_ini->enableDFSChnlScan);
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableDFSPnoChnlScan] Value = [%u] ",pHddCtx->cfg_ini->enableDFSPnoChnlScan);
@@ -4292,6 +4475,66 @@ static void print_hdd_cfg(hdd_context_t *pHddCtx)
"Name = [gPERRoamCCAEnabled] Value = [%u] ",
pHddCtx->cfg_ini->isPERRoamCCAEnabled);
+#ifdef DHCP_SERVER_OFFLOAD
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+ "Name = [gDHCPServerOffloadEnable] Value = [%u]",
+ pHddCtx->cfg_ini->enable_dhcp_srv_offload);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+ "Name = [gDHCPMaxNumClients] Value = [%u]",
+ pHddCtx->cfg_ini->dhcp_max_num_clients);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+ "Name = [gDHCPServerIP] Value = [%s]",
+ pHddCtx->cfg_ini->dhcp_srv_ip);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+ "Name = [gDHCPStartLsb] Value = [%u]",
+ pHddCtx->cfg_ini->dhcp_start_lsb);
+#endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+ "Name = [gMDNSOffloadEnable] Value = [%u]",
+ pHddCtx->cfg_ini->enable_mdns_offload);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+ "Name = [gMDNSFqdn] Value = [%s]",
+ pHddCtx->cfg_ini->mdns_fqdn);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+ "Name = [gMDNSUniqueFqdn] Value = [%s]",
+ pHddCtx->cfg_ini->mdns_uniquefqdn);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+ "Name = [gMDNSResponseTypeA] Value = [%s]",
+ pHddCtx->cfg_ini->mdns_resp_type_a);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+ "Name = [gMDNSResponseTypeAIpv4Addr] Value = [%u]",
+ pHddCtx->cfg_ini->mdns_resp_type_a_ipv4);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+ "Name = [gMDNSResponseTypeTXT] Value = [%s]",
+ pHddCtx->cfg_ini->mdns_resp_type_txt);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+ "Name = [gMDNSResponseTypeTXTContent] Value = [%s]",
+ pHddCtx->cfg_ini->mdns_resp_type_txt_content);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+ "Name = [gMDNSResponseTypePTR] Value = [%s]",
+ pHddCtx->cfg_ini->mdns_resp_type_ptr);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+ "Name = [gMDNSResponseTypePTRDomainName] Value = [%s]",
+ pHddCtx->cfg_ini->mdns_resp_type_ptr_dname);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+ "Name = [gMDNSResponseTypeSRV] Value = [%s]",
+ pHddCtx->cfg_ini->mdns_resp_type_srv);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+ "Name = [gMDNSResponseTypeSRVPriority] Value = [%u]",
+ pHddCtx->cfg_ini->mdns_resp_type_srv_priority);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+ "Name = [gMDNSResponseTypeSRVWeight] Value = [%u]",
+ pHddCtx->cfg_ini->mdns_resp_type_srv_weight);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+ "Name = [gMDNSResponseTypeSRVPort] Value = [%u]",
+ pHddCtx->cfg_ini->mdns_resp_type_srv_port);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+ "Name = [gMDNSResponseTypeSRVTarget] Value = [%s]",
+ pHddCtx->cfg_ini->mdns_resp_type_srv_target);
+#endif /* MDNS_OFFLOAD */
+
+
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
"Name = [gPERRoamFullScanThreshold] Value = [%u] ",
pHddCtx->cfg_ini->PERRoamFullScanThreshold);
@@ -4319,11 +4562,30 @@ static void print_hdd_cfg(hdd_context_t *pHddCtx)
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
"Name = [gDisableScanDuringSco] Value = [%u] ",
pHddCtx->cfg_ini->disable_scan_during_sco);
-
+#endif
+#ifdef SAP_AUTH_OFFLOAD
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+ "Name = [gEnableSAPAuthOffload] Value = [%u] ",
+ pHddCtx->cfg_ini->enable_sap_auth_offload);
#endif
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
"Name = [gEnableSapInternalRestart] Value = [%u] ",
pHddCtx->cfg_ini->sap_internal_restart);
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+ "Name = [gEnableLFRMBB] Value = [%u] ",
+ pHddCtx->cfg_ini->enable_lfr_mbb);
+#endif
+
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+ "Name = [sta_auth_retries_for_code17] Value = [%u] ",
+ pHddCtx->cfg_ini->sta_auth_retries_for_code17);
+
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+ "Name = [%s] Value = [%u] ",
+ CFG_TRIGGER_NULLFRAME_BEFORE_HB_NAME,
+ pHddCtx->cfg_ini->trigger_nullframe_before_hb);
}
@@ -4844,8 +5106,9 @@ static void hdd_set_power_save_config(hdd_context_t *pHddCtx, tSmeConfigParams *
}
-#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
-static VOS_STATUS hdd_string_to_u8_array( char *str, tANI_U8 *intArray, tANI_U8 *len, tANI_U8 intArrayMaxLen )
+VOS_STATUS hdd_string_to_u8_array(char *str, tANI_U8 *intArray,
+ tANI_U8 *len, tANI_U8 intArrayMaxLen,
+ char *seperator)
{
char *s = str;
@@ -4862,10 +5125,12 @@ static VOS_STATUS hdd_string_to_u8_array( char *str, tANI_U8 *intArray, tANI_U8
//Any other return value means error. Ignore it.
if( sscanf(s, "%d", &val ) == 1 )
{
+ if (val > 255 || val < 0)
+ return VOS_STATUS_E_FAILURE;
intArray[*len] = (tANI_U8) val;
*len += 1;
}
- s = strpbrk( s, "," );
+ s = strpbrk( s, seperator);
if( s )
s++;
}
@@ -4873,8 +5138,58 @@ static VOS_STATUS hdd_string_to_u8_array( char *str, tANI_U8 *intArray, tANI_U8
return VOS_STATUS_SUCCESS;
}
-#endif
+#ifdef MDNS_OFFLOAD
+int hdd_string_to_string_array(char *data, uint8_t *datalist,
+ char separator, uint8_t *num_entries,
+ uint8_t max_entries,
+ uint8_t max_len_entry)
+{
+ uint8_t num = 0;
+ char *str = NULL;
+ char *temp_str = NULL;
+ char *field;
+ uint16_t len = 0;
+
+ if ((data == NULL) || ( datalist == NULL) || (num_entries == NULL))
+ return VOS_STATUS_E_INVAL;
+
+ str = vos_mem_malloc(strlen((char *)data));
+ if (!str) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s str allocation failed",__func__);
+ return -ENOMEM;
+ }
+ vos_mem_copy(str, data, strlen((char *)data));
+ temp_str = str;
+ /* parse the string */
+ while (str && ('\0' != *str) && (num < max_entries)) {
+ field = str;
+ while (str && ('\0' != *str) && (separator != *str))
+ str++;
+ if ('\0' == *str) {
+ /* reach the end of string */
+ if ('\0' != *field) {
+ strlcpy((char *)(datalist +
+ (num * max_len_entry)),
+ field, max_len_entry);
+ num++;
+ }
+ break;
+ }
+ /* replace separator with NULL to terminate the data */
+ *str++ = '\0';
+ len = (char *)str - (char *)field;
+ strlcpy((char *)(datalist + (num * max_len_entry)),
+ field, len);
+ num++;
+ }
+ *num_entries = num;
+ vos_mem_free(temp_str);
+
+ return 0;
+}
+#endif /* MDNS_OFFLOAD */
v_BOOL_t hdd_update_config_dat( hdd_context_t *pHddCtx )
{
@@ -5282,13 +5597,6 @@ v_BOOL_t hdd_update_config_dat( hdd_context_t *pHddCtx )
hddLog(LOGE,"Failure: Could not pass on WNI_CFG_HEART_BEAT_THRESHOLD configuration info to CCM" );
}
- if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD, pConfig->apDataAvailPollPeriodInMs,
- NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
- {
- fStatus = FALSE;
- hddLog(LOGE,"Failure: Could not pass on WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD configuration info to CCM" );
- }
-
if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ENABLE_CLOSE_LOOP,
pConfig->enableCloseLoop, NULL, eANI_BOOLEAN_FALSE)
==eHAL_STATUS_FAILURE)
@@ -5865,6 +6173,14 @@ v_BOOL_t hdd_update_config_dat( hdd_context_t *pHddCtx )
hddLog(LOGE, "Could not pass on WNI_CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN ");
}
+ if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL,
+ pConfig->btc_disable_wlan_link_critical, NULL,
+ eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
+ {
+ fStatus = FALSE;
+ hddLog(LOGE, "Could not pass on WNI_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL");
+ }
+
if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LINK_FAIL_TIMEOUT,
pConfig->linkFailTimeout, NULL,
eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
@@ -5917,6 +6233,22 @@ v_BOOL_t hdd_update_config_dat( hdd_context_t *pHddCtx )
fStatus = FALSE;
hddLog(LOGE, "Could not pass on WNI_CFG_DISABLE_BAR_WAKE_UP_HOST to CCM");
}
+
+ if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_SAR_BOFFSET_SET_CORRECTION,
+ pConfig->boffset_correction_enable,
+ NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
+ {
+ fStatus = FALSE;
+ hddLog(LOGE, "Could not pass on WNI_CFG_SAR_BOFFSET_SET_CORRECTION to CCM");
+ }
+
+ if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_DISABLE_SCAN_DURING_SCO,
+ pConfig->disable_scan_during_sco,
+ NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
+ {
+ fStatus = FALSE;
+ hddLog(LOGE, "Could not pass on WNI_CFG_DISABLE_SCAN_DURING_SCO to CCM");
+ }
if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ENABLE_CONC_BMISS,
pConfig->enable_conc_bmiss, NULL, eANI_BOOLEAN_FALSE)
==eHAL_STATUS_FAILURE)
@@ -5932,22 +6264,14 @@ v_BOOL_t hdd_update_config_dat( hdd_context_t *pHddCtx )
hddLog(LOGE, "Could not pass on WNI_CFG_ENABLE_UNITS_BWAIT to CCM");
}
- if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_SAR_BOFFSET_SET_CORRECTION,
- pConfig->boffset_correction_enable,
- NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
- {
- fStatus = FALSE;
- hddLog(LOGE, "Could not pass on WNI_CFG_SAR_BOFFSET_SET_CORRECTION to CCM");
- }
-
- if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_DISABLE_SCAN_DURING_SCO,
- pConfig->disable_scan_during_sco,
- NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
+ if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TRIGGER_NULLFRAME_BEFORE_HB,
+ pConfig->trigger_nullframe_before_hb, NULL,
+ eANI_BOOLEAN_FALSE)
+ ==eHAL_STATUS_FAILURE)
{
fStatus = FALSE;
- hddLog(LOGE, "Could not pass on WNI_CFG_DISABLE_SCAN_DURING_SCO to CCM");
+ hddLog(LOGE, "Couldn't pass WNI_CFG_TRIGGER_NULLFRAME_BEFORE_HB to CCM");
}
-
return fStatus;
}
@@ -6162,6 +6486,11 @@ VOS_STATUS hdd_set_sme_config( hdd_context_t *pHddCtx )
smeConfig->csrConfig.bFastRoamInConIniFeatureEnabled = 0;
}
#endif
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ smeConfig->csrConfig.enable_lfr_mbb = pConfig->enable_lfr_mbb;
+#endif
+
#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
smeConfig->csrConfig.neighborRoamConfig.nNeighborReassocRssiThreshold = pConfig->nNeighborReassocRssiThreshold;
smeConfig->csrConfig.neighborRoamConfig.nNeighborLookupRssiThreshold = pConfig->nNeighborLookupRssiThreshold;
@@ -6179,10 +6508,12 @@ VOS_STATUS hdd_set_sme_config( hdd_context_t *pHddCtx )
smeConfig->csrConfig.neighborRoamConfig.nNeighborInitialForcedRoamTo5GhEnable
= pConfig->nNeighborInitialForcedRoamTo5GhEnable;
}
+ smeConfig->csrConfig.neighborRoamConfig.nWeakZoneRssiThresholdForRoam =
+ pConfig->nWeakZoneRssiThresholdForRoam;
hdd_string_to_u8_array( pConfig->neighborScanChanList,
smeConfig->csrConfig.neighborRoamConfig.neighborScanChanList.channelList,
&smeConfig->csrConfig.neighborRoamConfig.neighborScanChanList.numChannels,
- WNI_CFG_VALID_CHANNEL_LIST_LEN );
+ WNI_CFG_VALID_CHANNEL_LIST_LEN, "," );
#endif
smeConfig->csrConfig.addTSWhenACMIsOff = pConfig->AddTSWhenACMIsOff;
@@ -6260,6 +6591,8 @@ VOS_STATUS hdd_set_sme_config( hdd_context_t *pHddCtx )
smeConfig->csrConfig.edca_be_aifs =
pHddCtx->cfg_ini->edca_be_aifs;
+ smeConfig->csrConfig.sta_auth_retries_for_code17 =
+ pHddCtx->cfg_ini->sta_auth_retries_for_code17;
sme_set_mgmt_frm_via_wq5((tHalHandle)(pHddCtx->hHal),
pHddCtx->cfg_ini->sendMgmtPktViaWQ5);
diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg80211.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg80211.c
index 4eda9428042..c9c56e849a3 100644
--- a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -183,6 +183,10 @@
#define MAC_ADDR_SPOOFING_FW_ENABLE_HOST_DISABLE 2
#define MAC_ADDR_SPOOFING_DEFER_INTERVAL 10 //in ms
+/*
+ * max_sched_scan_plans defined to 10
+ */
+#define MAX_SCHED_SCAN_PLANS 10
static const u32 hdd_cipher_suites[] =
{
@@ -776,6 +780,538 @@ inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
}
+/*
+ * define short names for the global vendor params
+ * used by __wlan_hdd_cfg80211_get_station_cmd()
+ */
+#define STATION_INVALID \
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID
+#define STATION_INFO \
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO
+#define STATION_ASSOC_FAIL_REASON \
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON
+#define STATION_MAX \
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX
+
+static const struct nla_policy
+hdd_get_station_policy[STATION_MAX + 1] = {
+ [STATION_INFO] = {.type = NLA_FLAG},
+ [STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG},
+};
+
+/**
+ * hdd_get_station_assoc_fail() - Handle get station assoc fail
+ * @hdd_ctx: HDD context within host driver
+ * @wdev: wireless device
+ *
+ * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL.
+ * Validate cmd attributes and send the station info to upper layers.
+ *
+ * Return: Success(0) or reason code for failure
+ */
+static int hdd_get_station_assoc_fail(hdd_context_t *hdd_ctx,
+ hdd_adapter_t *adapter)
+{
+ struct sk_buff *skb = NULL;
+ uint32_t nl_buf_len;
+ hdd_station_ctx_t *hdd_sta_ctx;
+
+ nl_buf_len = NLMSG_HDRLEN;
+ nl_buf_len += sizeof(uint32_t);
+ skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
+
+ if (!skb) {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"cfg80211_vendor_cmd_alloc_reply_skb failed");
+ return -ENOMEM;
+ }
+
+ hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+ if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON,
+ hdd_sta_ctx->conn_info.assoc_status_code)) {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
+ goto fail;
+ }
+ return cfg80211_vendor_cmd_reply(skb);
+fail:
+ if (skb)
+ kfree_skb(skb);
+ return -EINVAL;
+}
+
+/**
+ * hdd_map_auth_type() - transform auth type specific to
+ * vendor command
+ * @auth_type: csr auth type
+ *
+ * Return: Success(0) or reason code for failure
+ */
+static int hdd_convert_auth_type(uint32_t auth_type)
+{
+ uint32_t ret_val;
+
+ switch (auth_type) {
+ case eCSR_AUTH_TYPE_OPEN_SYSTEM:
+ ret_val = QCA_WLAN_AUTH_TYPE_OPEN;
+ break;
+ case eCSR_AUTH_TYPE_SHARED_KEY:
+ ret_val = QCA_WLAN_AUTH_TYPE_SHARED;
+ break;
+ case eCSR_AUTH_TYPE_WPA:
+ ret_val = QCA_WLAN_AUTH_TYPE_WPA;
+ break;
+ case eCSR_AUTH_TYPE_WPA_PSK:
+ ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK;
+ break;
+ case eCSR_AUTH_TYPE_AUTOSWITCH:
+ ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH;
+ break;
+ case eCSR_AUTH_TYPE_WPA_NONE:
+ ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE;
+ break;
+ case eCSR_AUTH_TYPE_RSN:
+ ret_val = QCA_WLAN_AUTH_TYPE_RSN;
+ break;
+ case eCSR_AUTH_TYPE_RSN_PSK:
+ ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK;
+ break;
+ case eCSR_AUTH_TYPE_FT_RSN:
+ ret_val = QCA_WLAN_AUTH_TYPE_FT;
+ break;
+ case eCSR_AUTH_TYPE_FT_RSN_PSK:
+ ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK;
+ break;
+ case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
+ ret_val = QCA_WLAN_AUTH_TYPE_WAI;
+ break;
+ case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
+ ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK;
+ break;
+#ifdef FEATURE_WLAN_ESE
+ case eCSR_AUTH_TYPE_CCKM_WPA:
+ ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
+ break;
+ case eCSR_AUTH_TYPE_CCKM_RSN:
+ ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
+ break;
+#endif
+ case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
+ ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK;
+ break;
+ case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
+ ret_val = QCA_WLAN_AUTH_TYPE_SHA256;
+ break;
+ case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
+ case eCSR_AUTH_TYPE_FAILED:
+ case eCSR_AUTH_TYPE_NONE:
+ default:
+ ret_val = QCA_WLAN_AUTH_TYPE_INVALID;
+ break;
+ }
+ return ret_val;
+}
+
+/**
+ * hdd_map_dot_11_mode() - transform dot11mode type specific to
+ * vendor command
+ * @dot11mode: dot11mode
+ *
+ * Return: Success(0) or reason code for failure
+ */
+static int hdd_convert_dot11mode(uint32_t dot11mode)
+{
+ uint32_t ret_val;
+
+ switch (dot11mode) {
+ case eCSR_CFG_DOT11_MODE_11A:
+ ret_val = QCA_WLAN_802_11_MODE_11A;
+ break;
+ case eCSR_CFG_DOT11_MODE_11B:
+ ret_val = QCA_WLAN_802_11_MODE_11B;
+ break;
+ case eCSR_CFG_DOT11_MODE_11G:
+ ret_val = QCA_WLAN_802_11_MODE_11G;
+ break;
+ case eCSR_CFG_DOT11_MODE_11N:
+ ret_val = QCA_WLAN_802_11_MODE_11N;
+ break;
+ case eCSR_CFG_DOT11_MODE_11AC:
+ ret_val = QCA_WLAN_802_11_MODE_11AC;
+ break;
+ case eCSR_CFG_DOT11_MODE_AUTO:
+ case eCSR_CFG_DOT11_MODE_ABG:
+ default:
+ ret_val = QCA_WLAN_802_11_MODE_INVALID;
+ }
+ return ret_val;
+}
+
+/**
+ * hdd_add_tx_bitrate() - add tx bitrate attribute
+ * @skb: pointer to sk buff
+ * @hdd_sta_ctx: pointer to hdd station context
+ * @idx: attribute index
+ *
+ * Return: Success(0) or reason code for failure
+ */
+static int32_t hdd_add_tx_bitrate(struct sk_buff *skb,
+ hdd_station_ctx_t *hdd_sta_ctx,
+ int idx)
+{
+ struct nlattr *nla_attr;
+ uint32_t bitrate, bitrate_compat;
+
+ nla_attr = nla_nest_start(skb, idx);
+ if (!nla_attr)
+ goto fail;
+ /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
+ bitrate = cfg80211_calculate_bitrate(&hdd_sta_ctx->conn_info.txrate);
+
+ /* report 16-bit bitrate only if we can */
+ bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
+ if (bitrate > 0 &&
+ nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
+ goto fail;
+ }
+ if (bitrate_compat > 0 &&
+ nla_put_u16(skb, NL80211_RATE_INFO_BITRATE, bitrate_compat)) {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
+ goto fail;
+ }
+ if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
+ hdd_sta_ctx->conn_info.txrate.nss)) {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
+ goto fail;
+ }
+ nla_nest_end(skb, nla_attr);
+ return 0;
+fail:
+ return -EINVAL;
+}
+
+/**
+ * hdd_add_sta_info() - add station info attribute
+ * @skb: pointer to sk buff
+ * @hdd_sta_ctx: pointer to hdd station context
+ * @idx: attribute index
+ *
+ * Return: Success(0) or reason code for failure
+ */
+static int32_t hdd_add_sta_info(struct sk_buff *skb,
+ hdd_station_ctx_t *hdd_sta_ctx, int idx)
+{
+ struct nlattr *nla_attr;
+
+ nla_attr = nla_nest_start(skb, idx);
+ if (!nla_attr)
+ goto fail;
+ if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
+ (hdd_sta_ctx->conn_info.signal + 100))) {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
+ goto fail;
+ }
+ if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE))
+ goto fail;
+ nla_nest_end(skb, nla_attr);
+ return 0;
+fail:
+ return -EINVAL;
+}
+
+/**
+ * hdd_add_survey_info() - add survey info attribute
+ * @skb: pointer to sk buff
+ * @hdd_sta_ctx: pointer to hdd station context
+ * @idx: attribute index
+ *
+ * Return: Success(0) or reason code for failure
+ */
+static int32_t hdd_add_survey_info(struct sk_buff *skb,
+ hdd_station_ctx_t *hdd_sta_ctx,
+ int idx)
+{
+ struct nlattr *nla_attr;
+
+ nla_attr = nla_nest_start(skb, idx);
+ if (!nla_attr)
+ goto fail;
+ if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
+ hdd_sta_ctx->conn_info.freq) ||
+ nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
+ (hdd_sta_ctx->conn_info.noise + 100))) {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
+ goto fail;
+ }
+ nla_nest_end(skb, nla_attr);
+ return 0;
+fail:
+ return -EINVAL;
+}
+
+/**
+ * hdd_add_link_standard_info() - add link info attribute
+ * @skb: pointer to sk buff
+ * @hdd_sta_ctx: pointer to hdd station context
+ * @idx: attribute index
+ *
+ * Return: Success(0) or reason code for failure
+ */
+static int32_t
+hdd_add_link_standard_info(struct sk_buff *skb,
+ hdd_station_ctx_t *hdd_sta_ctx, int idx)
+{
+ struct nlattr *nla_attr;
+
+ nla_attr = nla_nest_start(skb, idx);
+ if (!nla_attr)
+ goto fail;
+ if (nla_put(skb,
+ NL80211_ATTR_SSID,
+ hdd_sta_ctx->conn_info.SSID.SSID.length,
+ hdd_sta_ctx->conn_info.SSID.SSID.ssId)) {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
+ goto fail;
+ }
+ if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO))
+ goto fail;
+ if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO))
+ goto fail;
+ nla_nest_end(skb, nla_attr);
+ return 0;
+fail:
+ return -EINVAL;
+}
+
+/**
+ * hdd_add_ap_standard_info() - add ap info attribute
+ * @skb: pointer to sk buff
+ * @hdd_sta_ctx: pointer to hdd station context
+ * @idx: attribute index
+ *
+ * Return: Success(0) or reason code for failure
+ */
+static int32_t
+hdd_add_ap_standard_info(struct sk_buff *skb,
+ hdd_station_ctx_t *hdd_sta_ctx, int idx)
+{
+ struct nlattr *nla_attr;
+
+ nla_attr = nla_nest_start(skb, idx);
+ if (!nla_attr)
+ goto fail;
+ if (hdd_sta_ctx->conn_info.conn_flag.vht_present)
+ if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
+ sizeof(hdd_sta_ctx->conn_info.vht_caps),
+ &hdd_sta_ctx->conn_info.vht_caps)) {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
+ goto fail;
+ }
+ if (hdd_sta_ctx->conn_info.conn_flag.ht_present)
+ if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
+ sizeof(hdd_sta_ctx->conn_info.ht_caps),
+ &hdd_sta_ctx->conn_info.ht_caps)) {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
+ goto fail;
+ }
+ nla_nest_end(skb, nla_attr);
+ return 0;
+fail:
+ return -EINVAL;
+}
+
+/**
+ * hdd_get_station_info() - send BSS information to supplicant
+ * @hdd_ctx: pointer to hdd context
+ * @adapter: pointer to adapter
+ *
+ * Return: 0 if success else error status
+ */
+static int hdd_get_station_info(hdd_context_t *hdd_ctx,
+ hdd_adapter_t *adapter)
+{
+ struct sk_buff *skb = NULL;
+ uint8_t *tmp_hs20 = NULL;
+ uint32_t nl_buf_len;
+ hdd_station_ctx_t *hdd_sta_ctx;
+
+ hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+ nl_buf_len = NLMSG_HDRLEN;
+ nl_buf_len += sizeof(hdd_sta_ctx->conn_info.SSID.SSID.length) +
+ sizeof(hdd_sta_ctx->conn_info.freq) +
+ sizeof(hdd_sta_ctx->conn_info.noise) +
+ sizeof(hdd_sta_ctx->conn_info.signal) +
+ (sizeof(uint32_t) * 2) +
+ sizeof(hdd_sta_ctx->conn_info.txrate.nss) +
+ sizeof(hdd_sta_ctx->conn_info.roam_count) +
+ sizeof(hdd_sta_ctx->conn_info.authType) +
+ sizeof(hdd_sta_ctx->conn_info.dot11Mode);
+ if (hdd_sta_ctx->conn_info.conn_flag.vht_present)
+ nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_caps);
+ if (hdd_sta_ctx->conn_info.conn_flag.ht_present)
+ nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_caps);
+ if (hdd_sta_ctx->conn_info.conn_flag.hs20_present) {
+ tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->conn_info.hs20vendor_ie);
+ nl_buf_len += (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) -
+ 1);
+ }
+ if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present)
+ nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_operation);
+ if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present)
+ nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_operation);
+
+
+ skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
+ if (!skb) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: %d cfg80211_vendor_cmd_alloc_reply_skb failed",
+ __func__, __LINE__);
+ return -ENOMEM;
+ }
+
+ if (hdd_add_link_standard_info(skb, hdd_sta_ctx,
+ LINK_INFO_STANDARD_NL80211_ATTR)) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
+ goto fail;
+ }
+ if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
+ AP_INFO_STANDARD_NL80211_ATTR)) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
+ goto fail;
+ }
+ if (nla_put_u32(skb, INFO_ROAM_COUNT,
+ hdd_sta_ctx->conn_info.roam_count) ||
+ nla_put_u32(skb, INFO_AKM,
+ hdd_convert_auth_type(
+ hdd_sta_ctx->conn_info.authType)) ||
+ nla_put_u32(skb, WLAN802_11_MODE,
+ hdd_convert_dot11mode(
+ hdd_sta_ctx->conn_info.dot11Mode))) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
+ goto fail;
+ }
+ if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present)
+ if (nla_put(skb, HT_OPERATION,
+ (sizeof(hdd_sta_ctx->conn_info.ht_operation)),
+ &hdd_sta_ctx->conn_info.ht_operation)) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
+ goto fail;
+ }
+ if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present)
+ if (nla_put(skb, VHT_OPERATION,
+ (sizeof(hdd_sta_ctx->conn_info.vht_operation)),
+ &hdd_sta_ctx->conn_info.vht_operation)) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
+ goto fail;
+ }
+ if (hdd_sta_ctx->conn_info.conn_flag.hs20_present)
+ if (nla_put(skb, AP_INFO_HS20_INDICATION,
+ (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) - 1),
+ tmp_hs20 + 1)) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
+ goto fail;
+ }
+
+ return cfg80211_vendor_cmd_reply(skb);
+fail:
+ if (skb)
+ kfree_skb(skb);
+ return -EINVAL;
+}
+
+/**
+ * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
+ * @wiphy: corestack handler
+ * @wdev: wireless device
+ * @data: data
+ * @data_len: data length
+ *
+ * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
+ * Validate cmd attributes and send the station info to upper layers.
+ *
+ * Return: Success(0) or reason code for failure
+ */
+static int32_t
+__hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data,
+ int data_len)
+{
+ hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
+ struct net_device *dev = wdev->netdev;
+ hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+ struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
+ int32_t status;
+
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"Enter");
+ if (VOS_FTM_MODE == hdd_get_conparam()) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Command not allowed in FTM mode");
+ status = -EPERM;
+ goto out;
+ }
+
+ status = wlan_hdd_validate_context(hdd_ctx);
+ if (0 != status)
+ goto out;
+
+
+ status = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX,
+ data, data_len, NULL);
+ if (status) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Invalid ATTR");
+ goto out;
+ }
+
+ /* Parse and fetch Command Type*/
+ if (tb[STATION_INFO]) {
+ status = hdd_get_station_info(hdd_ctx, adapter);
+ } else if (tb[STATION_ASSOC_FAIL_REASON]) {
+ status = hdd_get_station_assoc_fail(hdd_ctx, adapter);
+ } else {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"get station info cmd type failed");
+ status = -EINVAL;
+ goto out;
+ }
+ EXIT();
+out:
+ return status;
+}
+
+/**
+ * wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
+ * @wiphy: corestack handler
+ * @wdev: wireless device
+ * @data: data
+ * @data_len: data length
+ *
+ * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
+ * Validate cmd attributes and send the station info to upper layers.
+ *
+ * Return: Success(0) or reason code for failure
+ */
+static int32_t
+hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data,
+ int data_len)
+{
+ int ret;
+
+ vos_ssr_protect(__func__);
+ ret = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len);
+ vos_ssr_unprotect(__func__);
+
+ return ret;
+}
+
+/*
+ * undef short names defined for get station command
+ * used by __wlan_hdd_cfg80211_get_station_cmd()
+ */
+#undef STATION_INVALID
+#undef STATION_INFO
+#undef STATION_ASSOC_FAIL_REASON
+#undef STATION_MAX
#ifdef WLAN_FEATURE_LINK_LAYER_STATS
@@ -1733,7 +2269,7 @@ static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
(TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
{
- hddLog(VOS_TRACE_LEVEL_ERROR,
+ hddLog(VOS_TRACE_LEVEL_WARN,
FL("Link Layer Statistics not supported by Firmware"));
return -EINVAL;
}
@@ -2155,6 +2691,8 @@ wlan_hdd_extscan_config_policy
{ .type = NLA_U32 },
[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
{ .type = NLA_U32 },
+ [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] =
+ { .type = NLA_U32 },
[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
{ .type = NLA_U32 },
@@ -3804,13 +4342,20 @@ static int hdd_extscan_start_fill_bucket_channel_spec(
int rem1, rem2;
eHalStatus status;
tANI_U8 bktIndex, j, numChannels;
+ uint32_t expected_buckets;
tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
tANI_U32 passive_max_chn_time, active_max_chn_time;
+ expected_buckets = pReqMsg->numBuckets;
bktIndex = 0;
nla_for_each_nested(buckets,
tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
+ if (bktIndex >= expected_buckets) {
+ hddLog(LOGW, FL("ignoring excess buckets"));
+ break;
+ }
+
if (nla_parse(bucket,
QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
nla_data(buckets), nla_len(buckets),
@@ -6723,6 +7268,10 @@ static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
return cfg80211_vendor_cmd_reply(reply_skb);
}
+#define BEACON_MISS_THRESH_2_4 \
+ QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
+#define BEACON_MISS_THRESH_5_0 \
+ QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
@@ -6758,12 +7307,16 @@ static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
tModifyRoamParamsReqParams modifyRoamParamsReq;
eHalStatus status;
int ret_val;
+ uint8_t hb_thresh_val;
+
static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
[PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
[PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
[PARAM_GUARD_TIME] = { .type = NLA_U32},
[PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
{ .type = NLA_U32},
+ [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
+ [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
};
ENTER();
@@ -6886,6 +7439,50 @@ static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
}
+ if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
+ hb_thresh_val = nla_get_u8(
+ tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
+
+ hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
+ hb_thresh_val);
+ ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
+ WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
+ NULL, eANI_BOOLEAN_FALSE);
+
+ status = sme_update_hb_threshold(
+ (WLAN_HDD_GET_CTX(pAdapter))->hHal,
+ WNI_CFG_HEART_BEAT_THRESHOLD,
+ hb_thresh_val, eCSR_BAND_24);
+ if (eHAL_STATUS_SUCCESS != status) {
+ hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
+ vos_mem_free(pReq);
+ pReq = NULL;
+ return -EPERM;
+ }
+ }
+
+ if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
+ hb_thresh_val = nla_get_u8(
+ tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
+
+ hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
+ hb_thresh_val);
+ ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
+ WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
+ NULL, eANI_BOOLEAN_FALSE);
+
+ status = sme_update_hb_threshold(
+ (WLAN_HDD_GET_CTX(pAdapter))->hHal,
+ WNI_CFG_HEART_BEAT_THRESHOLD,
+ hb_thresh_val, eCSR_BAND_5G);
+ if (eHAL_STATUS_SUCCESS != status) {
+ hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
+ vos_mem_free(pReq);
+ pReq = NULL;
+ return -EPERM;
+ }
+ }
+
EXIT();
return ret_val;
}
@@ -6939,24 +7536,6 @@ qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
};
/**
- * hdd_test_con_alive() - check connection alive
- * @adapter: pointer to adapter
- *
- * Return: true if SME command is sent of false otherwise
- */
-static bool hdd_test_con_alive(hdd_adapter_t *adapter)
-{
- hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
-
- if (eHAL_STATUS_SUCCESS != sme_test_con_alive(hdd_ctx->hHal)) {
- hddLog(LOGE, FL("could not send ADDBA"));
- return false;
- }
-
- return true;
-}
-
-/**
* hdd_set_nud_stats_cb() - hdd callback api to get status
* @data: pointer to adapter
* @rsp: status
@@ -6974,8 +7553,6 @@ static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
if (VOS_STATUS_SUCCESS == rsp) {
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
"%s success received STATS_SET_START", __func__);
- if (adapter->nud_set_arp_stats)
- hdd_test_con_alive(adapter);
} else {
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
"%s STATS_SET_START Failed!!", __func__);
@@ -7036,18 +7613,15 @@ static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
return -EINVAL;
}
arp_stats_params.flag = true;
- adapter->nud_set_arp_stats = true;
arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
} else {
arp_stats_params.flag = false;
- adapter->nud_set_arp_stats = false;
}
- if (!arp_stats_params.flag) {
+ if (arp_stats_params.flag)
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
"%s STATS_SET_START Cleared!!", __func__);
- hdd_ctx->track_arp_ip = 0;
- vos_mem_zero(&adapter->hdd_stats.hddArpStats, sizeof(adapter->hdd_stats.hddArpStats));
- }
+ vos_mem_zero(&adapter->hdd_stats.hddArpStats,
+ sizeof(adapter->hdd_stats.hddArpStats));
arp_stats_params.pkt_type = 1; // ARP packet type
@@ -7152,65 +7726,6 @@ qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
[AP_LINK_DAD] = {.type = NLA_FLAG },
};
-/**
- * hdd_con_alive_cb() - Call back to get the connection status
- * @context: pointer to adapter
- *
- * Return: None
- */
-static void hdd_con_alive_cb(void *context, bool status)
-{
- hdd_adapter_t *adapter = (hdd_adapter_t *)context;
- adapter->con_status = status;
-}
-
-/**
- * hdd_get_con_alive() - get the connection status
- * @adapter: pointer to adapter
- *
- * Return: true if SME command is sent of false otherwise
- */
-static bool hdd_get_con_alive(hdd_adapter_t *adapter)
-{
- hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
- getConStatusParams conStatusParams;
-
- conStatusParams.rsp_cb_fn = hdd_con_alive_cb;
- conStatusParams.data_ctx = adapter;
-
- if (eHAL_STATUS_SUCCESS != sme_get_con_alive(hdd_ctx->hHal,
- &conStatusParams))
- {
- hddLog(LOGE, FL("could not get connection status"));
- return false;
- }
-
- return true;
-}
-
-/**
- * hdd_con_test_DELBA() - delete the BA session
- * @adapter: pointer to adapter
- *
- * Return: true if SME command is sent of false otherwise
- */
-static bool hdd_con_test_DELBA(hdd_adapter_t *adapter)
-{
- hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
- hdd_station_ctx_t *pHddStaCtx = &adapter->sessionCtx.station;
- uint8_t sta_id = pHddStaCtx->conn_info.staId[0];
-
- ENTER();
-
- if (eHAL_STATUS_SUCCESS != sme_test_con_delba((hdd_ctx->hHal), sta_id,
- adapter->sessionId)) {
- hddLog(LOGE, FL("could not send DELBA "));
- return false;
- }
-
- return true;
-}
-
static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
{
@@ -7265,8 +7780,6 @@ static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
if (0 != err)
return err;
- hdd_get_con_alive(adapter);
-
arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
arp_stats_params.data_ctx = adapter;
@@ -7309,7 +7822,7 @@ static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
}
if (nla_put_u16(skb, COUNT_FROM_NETDEV,
- adapter->hdd_stats.hddArpStats.tx_arp_req_count) ||
+ adapter->hdd_stats.hddArpStats.txCount) ||
nla_put_u16(skb, COUNT_TO_LOWER_MAC,
adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
@@ -7319,7 +7832,7 @@ static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
- adapter->hdd_stats.hddArpStats.rx_arp_rsp_count) ||
+ adapter->hdd_stats.hddArpStats.rxCount) ||
nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
adapter->hdd_stats.hddArpStats.rxDelivered) ||
nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
@@ -7328,15 +7841,11 @@ static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
kfree_skb(skb);
return -EINVAL;
}
- if (adapter->con_status) {
+ if (adapter->con_status)
nla_put_flag(skb, AP_LINK_ACTIVE);
- adapter->con_status = false;
- hdd_con_test_DELBA(adapter);
- }
if (adapter->dad)
nla_put_flag(skb, AP_LINK_DAD);
- hdd_ctx->track_arp_ip = 0;
cfg80211_vendor_cmd_reply(skb);
return err;
}
@@ -7366,6 +7875,76 @@ static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
#undef QCA_ATTR_NUD_STATS_GET_MAX
+
+
+#ifdef WLAN_FEATURE_APFIND
+/**
+ * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
+ * @wiphy: pointer to wireless wiphy structure.
+ * @wdev: pointer to wireless_dev structure.
+ * @data: pointer to apfind configuration data.
+ * @data_len: the length in byte of apfind data.
+ *
+ * This is called when wlan driver needs to send APFIND configurations to
+ * firmware.
+ *
+ * Return: An error code or 0 on success.
+ */
+static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data, int data_len)
+{
+ struct sme_ap_find_request_req apfind_req;
+ VOS_STATUS status;
+ int ret_val;
+ hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
+
+ ENTER();
+
+ ret_val = wlan_hdd_validate_context(hdd_ctx);
+ if (ret_val)
+ return ret_val;
+
+ if (VOS_FTM_MODE == hdd_get_conparam()) {
+ hddLog(LOGE, FL("Command not allowed in FTM mode"));
+ return -EPERM;
+ }
+
+ apfind_req.request_data_len = data_len;
+ apfind_req.request_data = data;
+
+ status = sme_apfind_set_cmd(&apfind_req);
+ if (VOS_STATUS_SUCCESS != status) {
+ ret_val = -EIO;
+ }
+ return ret_val;
+}
+
+/**
+ * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
+ * @wiphy: pointer to wireless wiphy structure.
+ * @wdev: pointer to wireless_dev structure.
+ * @data: pointer to apfind configuration data.
+ * @data_len: the length in byte of apfind data.
+ *
+ * This is called when wlan driver needs to send APFIND configurations to
+ * firmware.
+ *
+ * Return: An error code or 0 on success.
+ */
+static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data, int data_len)
+{
+ int ret;
+
+ vos_ssr_protect(__func__);
+ ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
+ vos_ssr_unprotect(__func__);
+
+ return ret;
+}
+#endif /* WLAN_FEATURE_APFIND */
const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
{
{
@@ -7596,6 +8175,15 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
WIPHY_VENDOR_CMD_NEED_RUNNING,
.doit = wlan_hdd_cfg80211_wifi_configuration_set
},
+#ifdef WLAN_FEATURE_APFIND
+ {
+ .info.vendor_id = QCA_NL80211_VENDOR_ID,
+ .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+ WIPHY_VENDOR_CMD_NEED_NETDEV,
+ .doit = wlan_hdd_cfg80211_apfind_cmd
+ },
+#endif /* WLAN_FEATURE_APFIND */
{
.info.vendor_id = QCA_NL80211_VENDOR_ID,
.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
@@ -7612,6 +8200,14 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
WIPHY_VENDOR_CMD_NEED_RUNNING,
.doit = wlan_hdd_cfg80211_get_nud_stats
},
+ {
+ .info.vendor_id = QCA_NL80211_VENDOR_ID,
+ .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+ WIPHY_VENDOR_CMD_NEED_NETDEV |
+ WIPHY_VENDOR_CMD_NEED_RUNNING,
+ .doit = hdd_cfg80211_get_station_cmd
+ },
};
/* vendor specific events */
@@ -7709,7 +8305,7 @@ struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
},
- {
+ [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
.vendor_id = QCA_NL80211_VENDOR_ID,
.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
},
@@ -7758,6 +8354,33 @@ struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
return wiphy;
}
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
+ defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
+/**
+ * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
+ * @wiphy: pointer to wiphy
+ * @config: pointer to config
+ *
+ * Return: None
+ */
+static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
+ hdd_config_t *config)
+{
+ wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
+ if (config->max_sched_scan_plan_interval)
+ wiphy->max_sched_scan_plan_interval =
+ config->max_sched_scan_plan_interval;
+ if (config->max_sched_scan_plan_iterations)
+ wiphy->max_sched_scan_plan_iterations =
+ config->max_sched_scan_plan_iterations;
+}
+#else
+static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
+ hdd_config_t *config)
+{
+}
+#endif
+
/*
* FUNCTION: wlan_hdd_cfg80211_update_band
* This function is called from the supplicant through a
@@ -8049,6 +8672,8 @@ int wlan_hdd_cfg80211_init(struct device *dev,
wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
+ hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
+
EXIT();
return 0;
}
@@ -8570,7 +9195,7 @@ static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
elem_id, elem_len, left);
return;
}
- if (IE_EID_VENDOR == elem_id)
+ if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
{
/* skipping the VSIE's which we don't want to include or
* it will be included by existing code
@@ -9105,6 +9730,118 @@ static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
return ret;
}
+#ifdef DHCP_SERVER_OFFLOAD
+void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
+ VOS_STATUS status)
+{
+ hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
+
+ ENTER();
+
+ if (NULL == adapter)
+ {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ "%s: adapter is NULL",__func__);
+ return;
+ }
+
+ adapter->dhcp_status.dhcp_offload_status = status;
+ vos_event_set(&adapter->dhcp_status.vos_event);
+ return;
+}
+
+/**
+ * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
+ * @hostapd_adapter: pointer to hostapd adapter.
+ * @re_init: flag set if api called post ssr
+ *
+ * Return: None
+ */
+VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
+ bool re_init)
+{
+ hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
+ sir_dhcp_srv_offload_info dhcp_srv_info;
+ tANI_U8 num_entries = 0;
+ tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
+ tANI_U8 num;
+ tANI_U32 temp;
+ VOS_STATUS ret;
+
+ ENTER();
+
+ if (!re_init) {
+ ret = wlan_hdd_validate_context(hdd_ctx);
+ if (0 != ret)
+ return VOS_STATUS_E_INVAL;
+ }
+
+ /* Prepare the request to send to SME */
+ dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
+ if (NULL == dhcp_srv_info) {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
+ return VOS_STATUS_E_NOMEM;
+ }
+
+ vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
+
+ dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
+ dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
+ dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
+ dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
+ dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
+ dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
+
+ hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
+ srv_ip,
+ &num_entries,
+ IPADDR_NUM_ENTRIES, ".");
+ if (num_entries != IPADDR_NUM_ENTRIES) {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ "%s: incorrect IP address (%s) assigned for DHCP server!",
+ __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
+ vos_mem_free(dhcp_srv_info);
+ return VOS_STATUS_E_FAILURE;
+ }
+
+ if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
+ __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
+ vos_mem_free(dhcp_srv_info);
+ return VOS_STATUS_E_FAILURE;
+ }
+
+ if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ "%s: invalid IP address (%s)! The last field must be less than 100!",
+ __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
+ vos_mem_free(dhcp_srv_info);
+ return VOS_STATUS_E_FAILURE;
+ }
+
+ for (num = 0; num < num_entries; num++) {
+ temp = srv_ip[num];
+ dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
+ }
+
+ if (eHAL_STATUS_SUCCESS !=
+ sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ "%s: sme_set_dhcp_srv_offload fail!", __func__);
+ vos_mem_free(dhcp_srv_info);
+ return VOS_STATUS_E_FAILURE;
+ }
+
+ hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
+ "%s: enable DHCP Server offload successfully!", __func__);
+
+ vos_mem_free(dhcp_srv_info);
+ return 0;
+}
+#endif /* DHCP_SERVER_OFFLOAD */
+
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
struct beacon_parameters *params)
@@ -9142,6 +9879,7 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
ENTER();
+ wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
iniConfig = pHddCtx->cfg_ini;
pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
@@ -9239,6 +9977,19 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
+#ifdef SAP_AUTH_OFFLOAD
+ /* In case of sap offload, hostapd.conf is configuted with open mode and
+ * security is configured from ini file. Due to open mode in hostapd.conf
+ * privacy bit is set to false which will result in not sending,
+ * data packets as encrypted.
+ * If enable_sap_auth_offload is enabled in ini and
+ * sap_auth_offload_sec_type is type of WPA2-PSK,
+ * driver will set privacy bit to 1.
+ */
+ if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
+ pHddCtx->cfg_ini->sap_auth_offload_sec_type)
+ pConfig->privacy = VOS_TRUE;
+#endif
(WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
@@ -9594,10 +10345,108 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
}
set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
+ if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
+ VOS_STATUS_SUCCESS)
+ {
+ hddLog(LOGE,FL("Fail to get Softap sessionID"));
+ VOS_ASSERT(0);
+ }
/* Initialize WMM configuation */
hdd_wmm_init(pHostapdAdapter);
wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
+#ifdef DHCP_SERVER_OFFLOAD
+ /* set dhcp server offload */
+ if (iniConfig->enable_dhcp_srv_offload &&
+ sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
+ vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
+ status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
+ if (!VOS_IS_STATUS_SUCCESS(status))
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ ("HDD DHCP Server Offload Failed!!"));
+ vos_event_reset(&pHostapdState->vosEvent);
+ if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
+ status = vos_wait_single_event(&pHostapdState->vosEvent,
+ 10000);
+ if (!VOS_IS_STATUS_SUCCESS(status)) {
+ hddLog(LOGE, FL("SAP Stop Failed"));
+ ret = -EINVAL;
+ goto error;
+ }
+ }
+ }
+ status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
+ if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
+ pHostapdAdapter->dhcp_status.dhcp_offload_status);
+ vos_event_reset(&pHostapdState->vosEvent);
+ if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
+ status = vos_wait_single_event(&pHostapdState->vosEvent,
+ 10000);
+ if (!VOS_IS_STATUS_SUCCESS(status)) {
+ hddLog(LOGE, FL("SAP Stop Failed"));
+ ret = -EINVAL;
+ goto error;
+ }
+ }
+ }
+#ifdef MDNS_OFFLOAD
+ if (iniConfig->enable_mdns_offload) {
+ vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
+ status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
+ if (VOS_IS_STATUS_SUCCESS(status))
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ ("HDD MDNS Server Offload Failed!!"));
+ vos_event_reset(&pHostapdState->vosEvent);
+ if (VOS_STATUS_SUCCESS ==
+ WLANSAP_StopBss(pHddCtx->pvosContext)) {
+ status = vos_wait_single_event(&pHostapdState->vosEvent,
+ 10000);
+ if (!VOS_IS_STATUS_SUCCESS(status)) {
+ hddLog(LOGE, FL("SAP Stop Failed"));
+ ret = -EINVAL;
+ goto error;
+ }
+ }
+ }
+ status = vos_wait_single_event(&pHostapdAdapter->
+ mdns_status.vos_event, 2000);
+ if (!VOS_IS_STATUS_SUCCESS(status) ||
+ pHostapdAdapter->mdns_status.mdns_enable_status ||
+ pHostapdAdapter->mdns_status.mdns_fqdn_status ||
+ pHostapdAdapter->mdns_status.mdns_resp_status)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
+ pHostapdAdapter->mdns_status.mdns_enable_status,
+ pHostapdAdapter->mdns_status.mdns_fqdn_status,
+ pHostapdAdapter->mdns_status.mdns_resp_status);
+ vos_event_reset(&pHostapdState->vosEvent);
+ if (VOS_STATUS_SUCCESS ==
+ WLANSAP_StopBss(pHddCtx->pvosContext)) {
+ status = vos_wait_single_event(&pHostapdState->vosEvent,
+ 10000);
+ if (!VOS_IS_STATUS_SUCCESS(status)) {
+ hddLog(LOGE, FL("SAP Stop Failed"));
+ ret = -EINVAL;
+ goto error;
+ }
+ }
+ }
+ }
+#endif /* MDNS_OFFLOAD */
+ } else {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ ("DHCP Disabled ini %d, FW %d"),
+ iniConfig->enable_dhcp_srv_offload,
+ sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
+ }
+#endif /* DHCP_SERVER_OFFLOAD */
+
#ifdef WLAN_FEATURE_P2P_DEBUG
if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
{
@@ -9615,6 +10464,8 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
}
}
#endif
+ /* Check and restart SAP if it is on Unsafe channel */
+ hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
pHostapdState->bCommit = TRUE;
EXIT();
@@ -11911,6 +12762,10 @@ static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
{
if ( (eCSR_ENCRYPT_TYPE_TKIP !=
pHddStaCtx->conn_info.ucEncryptionType) &&
+#ifdef FEATURE_WLAN_WAPI
+ (eCSR_ENCRYPT_TYPE_WPI !=
+ pHddStaCtx->conn_info.ucEncryptionType) &&
+#endif
(eCSR_ENCRYPT_TYPE_AES !=
pHddStaCtx->conn_info.ucEncryptionType)
)
@@ -12617,9 +13472,11 @@ VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
cfg80211_scan_request
- *scan_req)
+ *scan_req, hdd_context_t
+ *hdd_ctx)
{
- if (!scan_req || !scan_req->wiphy) {
+ if (!scan_req || !scan_req->wiphy ||
+ scan_req->wiphy != hdd_ctx->wiphy) {
hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
return false;
}
@@ -12632,9 +13489,11 @@ static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
#else
static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
cfg80211_scan_request
- *scan_req)
+ *scan_req, hdd_context_t
+ *hdd_ctx)
{
- if (!scan_req || !scan_req->wiphy) {
+ if (!scan_req || !scan_req->wiphy ||
+ scan_req->wiphy != hdd_ctx->wiphy) {
hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
return false;
}
@@ -12642,7 +13501,7 @@ static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
}
#endif
-
+#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
/*
* FUNCTION: hdd_cfg80211_scan_done_callback
* scanning callback function, called after finishing scan
@@ -12658,9 +13517,6 @@ static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
struct cfg80211_scan_request *req = NULL;
int ret = 0;
bool aborted = false;
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
- bool iface_down = false;
-#endif
long waitRet = 0;
tANI_U8 i;
hdd_context_t *pHddCtx;
@@ -12679,10 +13535,9 @@ static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
- if (!(pAdapter->dev->flags & IFF_UP))
+ if (!NET_DEV_IS_IFF_UP(pAdapter))
{
hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
- iface_down = true;
}
#endif
pScanInfo = &pHddCtx->scan_info;
@@ -12722,7 +13577,7 @@ static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
- if (!iface_down)
+ if (NET_DEV_IS_IFF_UP(pAdapter))
#endif
{
ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
@@ -12764,11 +13619,11 @@ static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
/* Scan is no longer pending */
pScanInfo->mScanPending = VOS_FALSE;
- if (!wlan_hdd_cfg80211_validate_scan_req(req))
+ if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
- iface_down ? "up" : "down");
+ NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
#endif
if (pAdapter->dev) {
@@ -12810,7 +13665,8 @@ static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
- if (!iface_down)
+ if (NET_DEV_IS_IFF_UP(pAdapter) &&
+ wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
#endif
cfg80211_scan_done(req, aborted);
@@ -12837,7 +13693,7 @@ allow_suspend:
hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
- if (!iface_down)
+ if (NET_DEV_IS_IFF_UP(pAdapter))
#endif
#ifdef FEATURE_WLAN_TDLS
wlan_hdd_tdls_scan_done_callback(pAdapter);
@@ -12880,7 +13736,7 @@ v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
(eConnectionState_Connecting ==
(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
{
- hddLog(VOS_TRACE_LEVEL_ERROR,
+ hddLog(LOG1,
"%s: %p(%d) Connection is in progress", __func__,
WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
if (session_id && reason)
@@ -12893,7 +13749,7 @@ v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
{
- hddLog(VOS_TRACE_LEVEL_ERROR,
+ hddLog(LOG1,
"%s: %p(%d) Reassociation is in progress", __func__,
WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
if (session_id && reason)
@@ -12912,7 +13768,7 @@ v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
(VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
{
staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
- hddLog(VOS_TRACE_LEVEL_ERROR,
+ hddLog(LOG1,
"%s: client " MAC_ADDRESS_STR
" is in the middle of WPS/EAPOL exchange.", __func__,
MAC_ADDR_ARRAY(staMac));
@@ -12942,7 +13798,7 @@ v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
{
staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
- hddLog(VOS_TRACE_LEVEL_ERROR,
+ hddLog(LOG1,
"%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
"middle of WPS/EAPOL exchange.", __func__,
MAC_ADDR_ARRAY(staMac));
@@ -13117,30 +13973,33 @@ int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
}
if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
{
- hddLog(VOS_TRACE_LEVEL_ERROR, FL("Scan not allowed"));
+
+ if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
+ hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
+ curr_session_id, curr_reason);
if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
pHddCtx->last_scan_reject_reason != curr_reason ||
!pHddCtx->last_scan_reject_timestamp)
{
pHddCtx->last_scan_reject_session_id = curr_session_id;
pHddCtx->last_scan_reject_reason = curr_reason;
- pHddCtx->last_scan_reject_timestamp = jiffies_to_msecs(jiffies);
+ pHddCtx->last_scan_reject_timestamp =
+ jiffies_to_msecs(jiffies) + SCAN_REJECT_THRESHOLD_TIME;
pHddCtx->scan_reject_cnt = 0;
}
else
{
pHddCtx->scan_reject_cnt++;
- hddLog(LOGE, FL("Reject cnt %d time delta %lu ms"), pHddCtx->scan_reject_cnt,
- (jiffies_to_msecs(jiffies) -
- pHddCtx->last_scan_reject_timestamp));
-
if ((pHddCtx->scan_reject_cnt >=
SCAN_REJECT_THRESHOLD) &&
- (jiffies_to_msecs(jiffies) -
- pHddCtx->last_scan_reject_timestamp) >=
- SCAN_REJECT_THRESHOLD_TIME)
+ vos_system_time_after(jiffies_to_msecs(jiffies),
+ pHddCtx->last_scan_reject_timestamp))
{
+ hddLog(LOGE, FL("Session %d reason %d reject cnt %d threshold time has elapsed? %d"),
+ curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
+ vos_system_time_after(jiffies_to_msecs(jiffies),
+ pHddCtx->last_scan_reject_timestamp));
pHddCtx->last_scan_reject_timestamp = 0;
pHddCtx->scan_reject_cnt = 0;
if (pHddCtx->cfg_ini->enableFatalEvent)
@@ -13605,6 +14464,7 @@ int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
int status = 0;
hdd_wext_state_t *pWextState;
hdd_context_t *pHddCtx;
+ hdd_station_ctx_t *hdd_sta_ctx;
v_U32_t roamId;
tCsrRoamProfile *pRoamProfile;
eCsrAuthType RSNAuthType;
@@ -13613,6 +14473,7 @@ int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
+ hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
status = wlan_hdd_validate_context(pHddCtx);
if (status)
@@ -13626,12 +14487,15 @@ int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
return -EINVAL;
}
+ wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
+
pRoamProfile = &pWextState->roamProfile;
if (pRoamProfile)
{
hdd_station_ctx_t *pHddStaCtx;
pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
+ pHddStaCtx->get_mgmt_log_sent = FALSE;
wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
@@ -13883,8 +14747,12 @@ static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
ENTER();
/* Should be in ieee802_11_defs.h */
+#ifndef WLAN_AKM_SUITE_8021X_SHA256
#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
+#endif
+#ifndef WLAN_AKM_SUITE_PSK_SHA256
#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
+#endif
/*set key mgmt type*/
switch(key_mgmt)
{
@@ -14600,7 +15468,7 @@ int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
* This function is used to disconnect from previous
* connection
*/
-static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
+int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
{
long ret = 0;
int status, result = 0;
@@ -14712,6 +15580,51 @@ static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
}
#endif
+/**
+ * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
+ * connect in HT20 mode
+ * @hdd_ctx: hdd context
+ * @adapter: Pointer to the HDD adapter
+ * @req: Pointer to the structure cfg_connect_params receieved from user space
+ *
+ * This function will check if supplicant has indicated to to connect in HT20
+ * mode. this is currently applicable only for 2.4Ghz mode only.
+ * if feature is enabled and supplicant indicate HT20 set
+ * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
+ *
+ * Return: void
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
+static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
+ hdd_adapter_t *adapter,
+ struct cfg80211_connect_params *req)
+{
+ hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
+ tCsrRoamProfile *roam_profile;
+
+ roam_profile = &wext_state->roamProfile;
+ roam_profile->force_24ghz_in_ht20 = false;
+ if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
+ !(req->ht_capa.cap_info &
+ IEEE80211_HT_CAP_SUP_WIDTH_20_40))
+ roam_profile->force_24ghz_in_ht20 = true;
+
+ hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
+ req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
+}
+#else
+static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
+ hdd_adapter_t *adapter,
+ struct cfg80211_connect_params *req)
+{
+ hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
+ tCsrRoamProfile *roam_profile;
+
+ roam_profile = &wext_state->roamProfile;
+ roam_profile->force_24ghz_in_ht20 = false;
+}
+#endif
+
/*
* FUNCTION: __wlan_hdd_cfg80211_connect
* This function is used to start the association process
@@ -14828,6 +15741,8 @@ static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
if (0 != status)
hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
+ wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
+
status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
req->ssid_len, req->bssid,
bssid_hint, channel);
@@ -14875,6 +15790,7 @@ int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
long ret;
+ eConnectionState prev_conn_state;
ENTER();
@@ -14895,6 +15811,8 @@ int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
* Calls hdd_DisConnectHandler.
*/
+ prev_conn_state = pHddStaCtx->conn_info.connState;
+
spin_lock_bh(&pAdapter->lock_for_active_session);
if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
{
@@ -14921,7 +15839,21 @@ int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
/*issue disconnect*/
status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
pAdapter->sessionId, reason);
- if(eHAL_STATUS_CMD_NOT_QUEUED == status)
+ if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
+ prev_conn_state != eConnectionState_Connecting)
+ {
+ hddLog(LOG1,
+ FL("status = %d, already disconnected"), status);
+ result = 0;
+ goto disconnected;
+ }
+ /*
+ * Wait here instead of returning directly, this will block the next
+ * connect command and allow processing of the scan for ssid and
+ * the previous connect command in CSR. Else we might hit some
+ * race conditions leading to SME and HDD out of sync.
+ */
+ else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
{
hddLog(LOG1,
FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
@@ -15076,7 +16008,10 @@ static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
}
}
#endif
- hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
+
+ hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
+ reasonCode,
+ pHddStaCtx->conn_info.connState);
status = wlan_hdd_disconnect(pAdapter, reasonCode);
if ( 0 != status )
{
@@ -15391,6 +16326,7 @@ static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
tCsrRoamProfile *pRoamProfile;
hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
int status;
+ eHalStatus hal_status;
#ifdef WLAN_FEATURE_RMC
tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
#endif
@@ -15463,8 +16399,23 @@ static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
/* Issue Disconnect request */
INIT_COMPLETION(pAdapter->disconnect_comp_var);
- sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
- eCSR_DISCONNECT_REASON_IBSS_LEAVE);
+ hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
+ pAdapter->sessionId,
+ eCSR_DISCONNECT_REASON_IBSS_LEAVE);
+ if (!HAL_STATUS_SUCCESS(hal_status)) {
+ hddLog(LOGE,
+ FL("sme_RoamDisconnect failed hal_status(%d)"),
+ hal_status);
+ return -EAGAIN;
+ }
+ status = wait_for_completion_timeout(
+ &pAdapter->disconnect_comp_var,
+ msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
+ if (!status) {
+ hddLog(LOGE,
+ FL("wait on disconnect_comp_var failed"));
+ return -ETIMEDOUT;
+ }
EXIT();
return 0;
@@ -15787,6 +16738,63 @@ static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
return ret;
}
+/*
+ * wlan_hdd_fill_summary_stats() - populate station_info summary stats
+ * @stats: summary stats to use as a source
+ * @info: kernel station_info struct to use as a destination
+ *
+ * Return: None
+ */
+static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
+ struct station_info *info)
+{
+ int i;
+
+ info->rx_packets = stats->rx_frm_cnt;
+ info->tx_packets = 0;
+ info->tx_retries = 0;
+ info->tx_failed = 0;
+
+ for (i = 0; i < 4; ++i) {
+ info->tx_packets += stats->tx_frm_cnt[i];
+ info->tx_retries += stats->multiple_retry_cnt[i];
+ info->tx_failed += stats->fail_cnt[i];
+ }
+
+ info->filled |= STATION_INFO_TX_PACKETS |
+ STATION_INFO_TX_RETRIES |
+ STATION_INFO_TX_FAILED |
+ STATION_INFO_RX_PACKETS;
+}
+
+/**
+ * wlan_hdd_get_sap_stats() - get aggregate SAP stats
+ * @adapter: sap adapter to get stats for
+ * @info: kernel station_info struct to populate
+ *
+ * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
+ * support "station dump" and "station get" for SAP vdevs, even though they
+ * aren't technically stations.
+ *
+ * Return: errno
+ */
+static int
+wlan_hdd_get_sap_stats(hdd_adapter_t *adapter, struct station_info *info)
+{
+ VOS_STATUS status;
+
+ status = wlan_hdd_get_station_stats(adapter);
+ if (!VOS_IS_STATUS_SUCCESS(status)) {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ "Failed to get SAP stats; status:%d", status);
+ return 0;
+ }
+
+ wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
+
+ return 0;
+}
+
static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
const u8* mac,
@@ -15810,6 +16818,7 @@ static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_devic
tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
tANI_U16 maxRate = 0;
+ int8_t snr = 0;
tANI_U16 myRate;
tANI_U16 currentRate = 0;
tANI_U8 maxSpeedMCS = 0;
@@ -15826,6 +16835,15 @@ static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_devic
ENTER();
+ status = wlan_hdd_validate_context(pHddCtx);
+ if (0 != status)
+ {
+ return status;
+ }
+
+ if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
+ return wlan_hdd_get_sap_stats(pAdapter, sinfo);
+
if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
(0 == ssidlen))
{
@@ -15844,16 +16862,13 @@ static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_devic
return 0;
}
- status = wlan_hdd_validate_context(pHddCtx);
- if (0 != status)
- {
- return status;
- }
-
wlan_hdd_get_station_stats(pAdapter);
rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
+ wlan_hdd_get_snr(pAdapter, &snr);
+ pHddStaCtx->conn_info.signal = sinfo->signal;
+ pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
sinfo->filled |= STATION_INFO_SIGNAL;
/*overwrite rate_flags if MAX link-speed need to be reported*/
@@ -16242,6 +17257,8 @@ static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_devic
sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
sinfo->filled |= STATION_INFO_RX_PACKETS;
+ vos_mem_copy(&pHddStaCtx->conn_info.txrate,
+ &sinfo->txrate, sizeof(sinfo->txrate));
if (rate_flags & eHAL_TX_RATE_LEGACY)
hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
@@ -16453,6 +17470,12 @@ static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
FL("psapCtx is NULL"));
return -ENOENT;
}
+ if (pHddCtx->cfg_ini->enable_sap_auth_offload)
+ {
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
+ "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
+ pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
+ }
if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
{
v_U16_t i;
@@ -16962,11 +17985,19 @@ static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
hdd_station_ctx_t *pStaCtx;
hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
int status = 0;
+
+ if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: PNO is allowed only in STA interface", __func__);
+ return eHAL_STATUS_FAILURE;
+ }
+
status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
/* The current firmware design does not allow PNO during any
- * active sessions. Hence, determine the active sessions
- * and return a failure.
+ * active sessions. PNO is allowed only in case when sap session
+ * is present and sapo auth offload feature enabled in firmare.
*/
while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
{
@@ -16977,7 +18008,8 @@ static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
&& (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
|| (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
|| (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
- || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
+ || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
+ !pHddCtx->cfg_ini->enable_sap_auth_offload)
|| (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
)
{
@@ -17021,6 +18053,69 @@ void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS s
EXIT();
}
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
+ defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
+/**
+ * hdd_config_sched_scan_plan() - configures the sched scan plans
+ * from the framework.
+ * @pno_req: pointer to PNO scan request
+ * @request: pointer to scan request from framework
+ *
+ * Return: None
+ */
+static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
+ struct cfg80211_sched_scan_request *request,
+ hdd_context_t *hdd_ctx)
+{
+ v_U32_t i = 0;
+
+ pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
+ for (i = 0; i < request->n_scan_plans; i++)
+ {
+ pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
+ request->scan_plans[i].iterations;
+ pno_req->scanTimers.aTimerValues[i].uTimerValue =
+ request->scan_plans[i].interval;
+ }
+}
+#else
+static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
+ struct cfg80211_sched_scan_request *request,
+ hdd_context_t *hdd_ctx)
+{
+ v_U32_t i, temp_int;
+ /* Driver gets only one time interval which is hardcoded in
+ * supplicant for 10000ms. Taking power consumption into account 6
+ * timers will be used, Timervalue is increased exponentially
+ * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
+ * timer is configurable through INI param gPNOScanTimerRepeatValue.
+ * If it is set to 0 only one timer will be used and PNO scan cycle
+ * will be repeated after each interval specified by supplicant
+ * till PNO is disabled.
+ */
+ if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
+ pno_req->scanTimers.ucScanTimersCount =
+ HDD_PNO_SCAN_TIMERS_SET_ONE;
+ else
+ pno_req->scanTimers.ucScanTimersCount =
+ HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
+
+ temp_int = (request->interval)/1000;
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "Base scan interval = %d PNOScanTimerRepeatValue = %d",
+ temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
+ for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
+ {
+ pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
+ hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
+ pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
+ temp_int *= 2;
+ }
+ //Repeat last timer until pno disabled.
+ pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
+}
+#endif
+
/*
* FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
* Function to enable PNO
@@ -17032,7 +18127,7 @@ static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
tSirPNOScanReq pnoRequest = {0};
hdd_context_t *pHddCtx;
tHalHandle hHal;
- v_U32_t i, indx, num_ch, tempInterval, j;
+ v_U32_t i, indx, num_ch, j;
u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
@@ -17069,7 +18164,6 @@ static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
MTRACE(vos_trace(VOS_MODULE_ID_HDD,
TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
pAdapter->sessionId, pAdapter->device_mode));
- sme_ScanFlushResult(hHal, pAdapter->sessionId);
ret = wlan_hdd_scan_abort(pAdapter);
if (ret < 0)
{
@@ -17276,34 +18370,7 @@ static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
pnoRequest.us5GProbeTemplateLen);
}
- /* Driver gets only one time interval which is hardcoded in
- * supplicant for 10000ms. Taking power consumption into account 6 timers
- * will be used, Timervalue is increased exponentially i.e 10,20,40,
- * 80,160,320 secs. And number of scan cycle for each timer
- * is configurable through INI param gPNOScanTimerRepeatValue.
- * If it is set to 0 only one timer will be used and PNO scan cycle
- * will be repeated after each interval specified by supplicant
- * till PNO is disabled.
- */
- if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
- pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
- else
- pnoRequest.scanTimers.ucScanTimersCount =
- HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
-
- tempInterval = (request->interval)/1000;
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "Base scan interval = %d PNOScanTimerRepeatValue = %d",
- tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
- for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
- {
- pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
- pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
- pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
- tempInterval *= 2;
- }
- //Repeat last timer until pno disabled.
- pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
+ hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
@@ -19249,6 +20316,7 @@ static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len
return -EINVAL;
}
+ vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
vos_mem_copy(hb_params, buf, buf_len);
smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
hb_params,
@@ -19288,6 +20356,7 @@ static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
}
#endif /* CONFIG_NL80211_TESTMODE */
+extern void hdd_set_wlan_suspend_mode(bool suspend);
static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
struct net_device *dev,
int idx, struct survey_info *survey)
@@ -19434,6 +20503,14 @@ int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
NO_SESSION, pHddCtx->isWiphySuspended));
+
+ if (pHddCtx->is_ap_mode_wow_supported)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "%s: Resume SoftAP", __func__);
+ hdd_set_wlan_suspend_mode(false);
+ }
+
spin_lock(&pHddCtx->schedScan_lock);
pHddCtx->isWiphySuspended = FALSE;
if (TRUE != pHddCtx->isSchedScanUpdatePending)
@@ -19518,6 +20595,12 @@ int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
return ret;
}
+ if (pHddCtx->is_ap_mode_wow_supported) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "%s: Suspend SoftAP", __func__);
+ hdd_set_wlan_suspend_mode(true);
+ }
+
MTRACE(vos_trace(VOS_MODULE_ID_HDD,
TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_dev_pwr.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_dev_pwr.c
index 275eeaf6d3e..d715393414b 100644
--- a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_dev_pwr.c
+++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_dev_pwr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -162,6 +162,10 @@ static int wlan_suspend(hdd_context_t* pHddCtx)
if ((vos_timer_get_system_time() - pHddCtx->last_suspend_success) >=
WLAN_POWER_COLLAPSE_FAIL_THRESHOLD)
{
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ FL("Current time: %lu Last suspend fail time: %lu continuous fail count: %d"),
+ vos_timer_get_system_time(), pHddCtx->last_suspend_success,
+ pHddCtx->continuous_suspend_fail_cnt);
pHddCtx->last_suspend_success = 0;
vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
WLAN_LOG_INDICATOR_HOST_DRIVER,
diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_early_suspend.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_early_suspend.c
index 57596797597..c14890ccb2e 100644
--- a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_early_suspend.c
+++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_early_suspend.c
@@ -98,7 +98,7 @@ static eHalStatus g_full_pwr_status;
static eHalStatus g_standby_status;
extern VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx);
-extern void hdd_wlan_initial_scan(hdd_context_t *pHddCtx);
+extern void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
extern struct notifier_block hdd_netdev_notifier;
extern tVOS_CON_MODE hdd_get_conparam ( void );
@@ -489,7 +489,7 @@ VOS_STATUS hdd_exit_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
//Trigger the initial scan
- hdd_wlan_initial_scan(pHddCtx);
+ hdd_wlan_initial_scan(pAdapter);
return VOS_STATUS_SUCCESS;
@@ -643,12 +643,16 @@ void hdd_conf_hostoffload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
}
if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
- (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
+ (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
+ ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
+ (pHddCtx->is_ap_mode_wow_supported)))
{
if (fenable)
{
- if (eConnectionState_Associated ==
- (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
+ if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
+ (eConnectionState_Associated ==
+ (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
+ || (WLAN_HDD_SOFTAP == pAdapter->device_mode))
{
if ((pHddCtx->cfg_ini->fhostArpOffload))
{
@@ -871,6 +875,8 @@ void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, int fenable)
i++;
}
}
+ /* store actual slots being used */
+ pAdapter->ns_slots = i;
read_unlock_bh(&in6_dev->lock);
vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
@@ -975,7 +981,7 @@ void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, int fenable)
hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD,
SIR_OFFLOAD_DISABLE);
- for (i = 0; i < slot_index; i++)
+ for (i = 0; i < pAdapter->ns_slots; i++)
{
hddLog(VOS_TRACE_LEVEL_INFO, FL("Disable Slot= %d"), i);
offLoadRequest.nsOffloadInfo.slotIdx = i;
@@ -987,6 +993,7 @@ void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, int fenable)
" %d Slot"), i);
}
}
+ pAdapter->ns_slots = 0;
}
end:
while (slot > 0 && selfIPv6Addr[--slot])
@@ -1468,6 +1475,26 @@ void hdd_mc_addr_list_cfg_config(hdd_context_t* pHddCtx, bool action)
}
}
+/**
+ * hdd_suspend_ind_callback: This API will set completion event for suspend
+ * @pAdapter: hdd_adapter_t
+ * @status: suspend status
+ *
+ * Return: none
+ */
+static void hdd_suspend_ind_callback(void *context, VOS_STATUS status)
+{
+ hdd_adapter_t *adapter = (hdd_adapter_t *)context;
+ if (NULL == adapter)
+ {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ "%s: HDD adapter is NULL",__func__);
+ return;
+ }
+ hddLog(VOS_TRACE_LEVEL_INFO, FL("suspend status %d"), status);
+ complete(&adapter->wlan_suspend_comp_var);
+}
+
static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx,
hdd_adapter_t *pAdapter)
{
@@ -1513,6 +1540,8 @@ static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx,
wlanSuspendParam->configuredMcstBcstFilterSetting =
pHddCtx->configuredMcastBcastFilter;
+ wlanSuspendParam->wlan_sus_callback = hdd_suspend_ind_callback;
+ wlanSuspendParam->context = pAdapter;
/* mc add list cfg item configuration in fwr */
hdd_mc_addr_list_cfg_config(pHddCtx, true);
@@ -1589,7 +1618,7 @@ void hdd_suspend_wlan(void)
{
hdd_context_t *pHddCtx = NULL;
v_CONTEXT_t pVosContext = NULL;
-
+ long ret;
VOS_STATUS status;
hdd_adapter_t *pAdapter = NULL;
hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
@@ -1673,9 +1702,17 @@ void hdd_suspend_wlan(void)
}
#endif
+ INIT_COMPLETION(pAdapter->wlan_suspend_comp_var);
/*Suspend notification sent down to driver*/
hdd_conf_suspend_ind(pHddCtx, pAdapter);
-
+ ret = wait_for_completion_interruptible_timeout(
+ &pAdapter->wlan_suspend_comp_var,
+ msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
+ if (0 >= ret)
+ {
+ hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on suspend failed %ld",
+ __func__, ret);
+ }
status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
pAdapterNode = pNext;
}
@@ -1946,6 +1983,8 @@ void hdd_resume_wlan(void)
hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
VOS_STATUS status;
v_CONTEXT_t pVosContext = NULL;
+ tPmcState pmc_state;
+ hdd_adapter_t *first_adapter = NULL;
hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
@@ -1980,6 +2019,26 @@ void hdd_resume_wlan(void)
pHddCtx->hdd_wlan_suspended = FALSE;
hdd_wlan_suspend_resume_event(HDD_WLAN_EARLY_RESUME);
+
+ /* Get first valid adapter for disable/enable bmps purpose */
+ status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
+ while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
+ {
+ first_adapter = pAdapterNode->pAdapter;
+ if (first_adapter != NULL)
+ break;
+ status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
+ pAdapterNode = pNext;
+ }
+ pmc_state = pmcGetPmcState(pHddCtx->hHal);
+ if (BMPS == pmc_state && first_adapter)
+ {
+ /* put the device into full power */
+ hddLog(VOS_TRACE_LEVEL_INFO,
+ "%s: Disaling bmps during resume", __func__);
+ wlan_hdd_enter_bmps(first_adapter, DRIVER_POWER_MODE_ACTIVE);
+ }
+
/*loop through all adapters. Concurrency */
status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
@@ -2027,14 +2086,8 @@ void hdd_resume_wlan(void)
"Switch to DTIM%d",powerRequest.uListenInterval);
sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
- if (BMPS == pmcGetPmcState(pHddCtx->hHal))
+ if (BMPS == pmc_state)
{
- /* put the device into full power */
- wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
-
- /* put the device back into BMPS */
- wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
-
pHddCtx->hdd_ignore_dtim_enabled = FALSE;
}
}
@@ -2044,6 +2097,15 @@ void hdd_resume_wlan(void)
pAdapterNode = pNext;
}
+ if (BMPS == pmc_state && first_adapter)
+ {
+ /* put the device into full power */
+ hddLog(VOS_TRACE_LEVEL_INFO,
+ "%s: Enable bmps during resume", __func__);
+ /* put the device back into BMPS */
+ wlan_hdd_enter_bmps(first_adapter, DRIVER_POWER_MODE_AUTO);
+ }
+
#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
{
@@ -2128,6 +2190,30 @@ static void hdd_ssr_timer_start(int msec)
ssr_timer_started = true;
}
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+/**
+ * hdd_wlan_ssr_shutdown_event()- send ssr shutdown state
+ *
+ * This Function send send ssr shutdown state diag event
+ *
+ * Return: void.
+ */
+static void hdd_wlan_ssr_shutdown_event(void)
+{
+ WLAN_VOS_DIAG_EVENT_DEF(ssr_shutdown,
+ struct host_event_wlan_ssr_shutdown);
+ vos_mem_zero(&ssr_shutdown, sizeof(ssr_shutdown));
+ ssr_shutdown.status = SSR_SUB_SYSTEM_SHUTDOWN;
+ WLAN_VOS_DIAG_EVENT_REPORT(&ssr_shutdown,
+ EVENT_WLAN_SSR_SHUTDOWN_SUBSYSTEM);
+}
+#else
+static inline void hdd_wlan_ssr_shutdown_event(void)
+{
+
+};
+#endif
+
/* the HDD interface to WLAN driver shutdown,
* the primary shutdown function in SSR
*/
@@ -2164,7 +2250,6 @@ VOS_STATUS hdd_wlan_shutdown(void)
{
vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
}
-
vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
vos_flush_work(&pHddCtx->sap_start_work);
hdd_reset_all_adapters(pHddCtx);
@@ -2313,11 +2398,81 @@ VOS_STATUS hdd_wlan_shutdown(void)
hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
__func__);
}
+ hdd_wlan_ssr_shutdown_event();
hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
,__func__);
return VOS_STATUS_SUCCESS;
}
+int hdd_dhcp_mdns_offload(hdd_adapter_t *adapter)
+{
+ hdd_config_t *config;
+ int status = VOS_STATUS_SUCCESS;
+ hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+ config = hdd_ctx->cfg_ini;
+ if (NULL == config) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ ("cfg_ini is NULL!!"));
+ return -EINVAL;
+ }
+#ifdef DHCP_SERVER_OFFLOAD
+ /* set dhcp server offload */
+ if (config->enable_dhcp_srv_offload &&
+ sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
+ vos_event_reset(&adapter->dhcp_status.vos_event);
+ status = wlan_hdd_set_dhcp_server_offload(adapter, true);
+ if (!VOS_IS_STATUS_SUCCESS(status))
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ ("HDD DHCP Server Offload Failed!!"));
+ return -EINVAL;
+ }
+ status = vos_wait_single_event(&adapter->dhcp_status.vos_event, 2000);
+ if (!VOS_IS_STATUS_SUCCESS(status) ||
+ adapter->dhcp_status.dhcp_offload_status)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
+ adapter->dhcp_status.dhcp_offload_status);
+ return -EINVAL;
+ }
+#ifdef MDNS_OFFLOAD
+ if (config->enable_mdns_offload) {
+ vos_event_reset(&adapter->mdns_status.vos_event);
+ status = wlan_hdd_set_mdns_offload(adapter);
+ if (VOS_IS_STATUS_SUCCESS(status))
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ ("HDD MDNS Server Offload Failed!!"));
+ return -EINVAL;
+ }
+ status = vos_wait_single_event(&adapter->
+ mdns_status.vos_event, 2000);
+ if (!VOS_IS_STATUS_SUCCESS(status) ||
+ adapter->mdns_status.mdns_enable_status ||
+ adapter->mdns_status.mdns_fqdn_status ||
+ adapter->mdns_status.mdns_resp_status)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
+ adapter->mdns_status.mdns_enable_status,
+ adapter->mdns_status.mdns_fqdn_status,
+ adapter->mdns_status.mdns_resp_status);
+ return -EINVAL;
+ }
+ }
+#endif /* MDNS_OFFLOAD */
+ } else {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ ("DHCP Disabled ini %d, FW %d"),
+ config->enable_dhcp_srv_offload,
+ sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
+ }
+#endif /* DHCP_SERVER_OFFLOAD */
+ return status;
+}
+
/**
* hdd_ssr_restart_sap() - restart sap on SSR
* @hdd_ctx: hdd context
@@ -2329,6 +2484,7 @@ static void hdd_ssr_restart_sap(hdd_context_t *hdd_ctx)
VOS_STATUS status;
hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
hdd_adapter_t *adapter;
+ hdd_hostapd_state_t *hostapd_state;
ENTER();
@@ -2337,8 +2493,29 @@ static void hdd_ssr_restart_sap(hdd_context_t *hdd_ctx)
adapter = adapter_node->pAdapter;
if (adapter && adapter->device_mode == WLAN_HDD_SOFTAP) {
if (test_bit(SOFTAP_INIT_DONE, &adapter->event_flags)) {
+ hostapd_state =
+ WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
hddLog(VOS_TRACE_LEVEL_INFO, FL("Restart prev SAP session"));
wlan_hdd_start_sap(adapter);
+ if (!VOS_IS_STATUS_SUCCESS(
+ hdd_dhcp_mdns_offload(adapter))) {
+ vos_event_reset(
+ &hostapd_state->vosEvent);
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ FL("DHCP/MDNS offload Failed!!"));
+ if (VOS_STATUS_SUCCESS ==
+ WLANSAP_StopBss(
+ hdd_ctx->pvosContext)) {
+ status = vos_wait_single_event(
+ &hostapd_state->vosEvent
+ , 10000);
+ if (!VOS_IS_STATUS_SUCCESS(
+ status)) {
+ hddLog(LOGE, FL("SAP Stop Failed"));
+ return;
+ }
+ }
+ }
}
}
status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
@@ -2348,6 +2525,29 @@ static void hdd_ssr_restart_sap(hdd_context_t *hdd_ctx)
EXIT();
}
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+/**
+* hdd_wlan_ssr_reinit_event()- send ssr reinit state
+*
+* This Function send send ssr reinit state diag event
+*
+* Return: void.
+*/
+static void hdd_wlan_ssr_reinit_event(void)
+{
+ WLAN_VOS_DIAG_EVENT_DEF(ssr_reinit, struct host_event_wlan_ssr_reinit);
+ vos_mem_zero(&ssr_reinit, sizeof(ssr_reinit));
+ ssr_reinit.status = SSR_SUB_SYSTEM_REINIT;
+ WLAN_VOS_DIAG_EVENT_REPORT(&ssr_reinit,
+ EVENT_WLAN_SSR_REINIT_SUBSYSTEM);
+}
+#else
+static inline void hdd_wlan_ssr_reinit_event(void)
+{
+
+}
+#endif
+
/* the HDD interface to WLAN driver re-init.
* This is called to initialize/start WLAN driver after a shutdown.
*/
@@ -2646,6 +2846,7 @@ err_re_init:
return -EPERM;
success:
+ hdd_wlan_ssr_reinit_event();
/* Trigger replay of BTC events */
send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_hostapd.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_hostapd.c
index ffe7cbae158..f318f1fadd9 100644
--- a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -79,6 +79,8 @@
#include "wlan_hdd_p2p.h"
#include "cfgApi.h"
#include "wniCfg.h"
+#include <wlan_hdd_wowl.h>
+#include "wlan_hdd_hostapd.h"
#ifdef FEATURE_WLAN_CH_AVOID
#include "wcnss_wlan.h"
@@ -408,6 +410,11 @@ static int hdd_hostapd_driver_command(hdd_adapter_t *pAdapter,
hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
tANI_U8 filterType = 0;
tANI_U8 *value;
+
+ ret = hdd_drv_cmd_validate(command, 8);
+ if (ret)
+ goto exit;
+
value = command + 9;
/* Convert the value from ascii to integer */
@@ -448,6 +455,10 @@ static int hdd_hostapd_driver_command(hdd_adapter_t *pAdapter,
}
else if (strncasecmp(command, "DISABLE_CA_EVENT", 16) == 0)
{
+ ret = hdd_drv_cmd_validate(command, 16);
+ if (ret)
+ goto exit;
+
ret = hdd_enable_disable_ca_event(pHddCtx, command, 16);
}
@@ -785,6 +796,54 @@ static int hdd_stop_bss_link(hdd_adapter_t *pHostapdAdapter,v_PVOID_t usrDataFor
return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
}
+#ifdef SAP_AUTH_OFFLOAD
+bool hdd_set_sap_auth_offload(hdd_adapter_t *pHostapdAdapter,
+ bool enabled)
+{
+ hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
+ struct tSirSapOffloadInfo sap_offload_info;
+
+ vos_mem_copy( &sap_offload_info.macAddr,
+ pHostapdAdapter->macAddressCurrent.bytes, VOS_MAC_ADDR_SIZE);
+
+ sap_offload_info.sap_auth_offload_enable = enabled;
+ sap_offload_info.sap_auth_offload_sec_type =
+ pHddCtx->cfg_ini->sap_auth_offload_sec_type;
+ sap_offload_info.key_len =
+ strlen(pHddCtx->cfg_ini->sap_auth_offload_key);
+
+ if (sap_offload_info.sap_auth_offload_enable &&
+ sap_offload_info.sap_auth_offload_sec_type)
+ {
+ if (sap_offload_info.key_len < 8 ||
+ sap_offload_info.key_len > WLAN_PSK_STRING_LENGTH)
+ {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ "%s: invalid key length(%d) of WPA security!", __func__,
+ sap_offload_info.key_len);
+ return false;
+ }
+ }
+ if (sap_offload_info.key_len)
+ {
+ vos_mem_copy(sap_offload_info.key,
+ pHddCtx->cfg_ini->sap_auth_offload_key,
+ sap_offload_info.key_len);
+ }
+ if (eHAL_STATUS_SUCCESS !=
+ sme_set_sap_auth_offload(pHddCtx->hHal, &sap_offload_info))
+ {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ "%s: sme_set_sap_auth_offload fail!", __func__);
+ return false;
+ }
+
+ hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
+ "%s: sme_set_sap_auth_offload successfully!", __func__);
+ return true;
+}
+#endif
+
VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCallback)
{
hdd_adapter_t *pHostapdAdapter;
@@ -1004,8 +1063,12 @@ VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCa
{
bAuthRequired = FALSE;
}
-
- if (bAuthRequired || bWPSState == eANI_BOOLEAN_TRUE )
+ /* fAuthRequiredshould should be false for sap offload */
+ if ((bAuthRequired || bWPSState)
+#ifdef SAP_AUTH_OFFLOAD
+ && !cfg_param->enable_sap_auth_offload
+#endif
+ )
{
vos_status = hdd_softap_RegisterSTA( pHostapdAdapter,
TRUE,
@@ -1553,6 +1616,43 @@ static void hdd_unsafe_channel_restart_sap(hdd_adapter_t *adapter,
return;
}
+void hdd_check_for_unsafe_ch(hdd_adapter_t *phostapd_adapter,
+ hdd_context_t *hdd_ctxt)
+{
+ v_U16_t channelLoop;
+ v_U16_t unsafeChannelCount = 0;
+ v_U16_t unsafeChannelList[NUM_20MHZ_RF_CHANNELS];
+
+ /* Get unsafe channel list */
+ vos_get_wlan_unsafe_channel(unsafeChannelList, sizeof(unsafeChannelList),
+ &unsafeChannelCount);
+ for (channelLoop = 0; channelLoop < unsafeChannelCount; channelLoop++)
+ {
+ if ((unsafeChannelList[channelLoop] ==
+ phostapd_adapter->sessionCtx.ap.operatingChannel)) {
+ if ((AUTO_CHANNEL_SELECT ==
+ phostapd_adapter->sessionCtx.ap.sapConfig.channel)
+ && (WLAN_HDD_SOFTAP == phostapd_adapter->device_mode)) {
+ /*
+ * current operating channel is un-safe channel
+ * restart driver
+ */
+ hdd_unsafe_channel_restart_sap(phostapd_adapter, hdd_ctxt);
+ /*
+ * On LE, this event is handled by wlan-services to
+ * restart SAP. On android, this event would be
+ * ignored.
+ */
+ wlan_hdd_send_svc_nlink_msg(WLAN_SVC_SAP_RESTART_IND,
+ NULL, 0);
+ }
+ break;
+ }
+ }
+ return;
+}
+
+
/**---------------------------------------------------------------------------
@@ -1717,28 +1817,9 @@ void hdd_hostapd_ch_avoid_cb
"%s : Current operation channel %d",
__func__,
pHostapdAdapter->sessionCtx.ap.operatingChannel);
- for (channelLoop = 0; channelLoop < unsafeChannelCount; channelLoop++)
- {
- if ((unsafeChannelList[channelLoop] ==
- pHostapdAdapter->sessionCtx.ap.operatingChannel))
- {
- if ((AUTO_CHANNEL_SELECT ==
- pHostapdAdapter->sessionCtx.ap.sapConfig.channel)
- && (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode))
- {
- /* current operating channel is un-safe channel
- * restart driver */
- hdd_unsafe_channel_restart_sap(pHostapdAdapter, hddCtxt);
- /* On LE, this event is handled by wlan-services to
- * restart SAP. On android, this event would be
- * ignored.
- */
- wlan_hdd_send_svc_nlink_msg(WLAN_SVC_SAP_RESTART_IND,
- NULL, 0);
- }
- return;
- }
- }
+ /* Check and Restart the SAP if it is on unsafe channel */
+ hdd_check_for_unsafe_ch(pHostapdAdapter, hddCtxt);
+
}
#ifdef WLAN_FEATURE_AP_HT40_24G
@@ -1873,6 +1954,7 @@ static __iw_softap_setparam(struct net_device *dev,
int set_value = value[1];
eHalStatus status;
int ret = 0; /* success */
+ int enable_pattrn_byte_match, enable_magic_pkt;
v_CONTEXT_t pVosContext;
ENTER();
@@ -2026,7 +2108,44 @@ static __iw_softap_setparam(struct net_device *dev,
}
case QCSAP_PARAM_SET_PROXIMITY:
{
- ret = wlan_hdd_set_proximity(set_value);
+ ret = wlan_hdd_set_proximity(set_value, hHal);
+ break;
+ }
+ case QCSAP_PARAM_SET_WOWL:
+ {
+ if (!pHddCtx->is_ap_mode_wow_supported)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: Not supported",__func__);
+ return -ENOTSUPP;
+ }
+ switch (set_value)
+ {
+ case 0x00:
+ hdd_exit_wowl(pHostapdAdapter, eWOWL_EXIT_USER);
+ break;
+ case 0x01:
+ case 0x02:
+ case 0x03:
+ enable_magic_pkt = (set_value & 0x01) ? 1 : 0;
+ enable_pattrn_byte_match = (set_value & 0x02) ? 1 : 0;
+ hddLog(LOGE, "magic packet ? = %s pattern byte matching ? = %s",
+ (enable_magic_pkt ? "YES":"NO"),
+ (enable_pattrn_byte_match ? "YES":"NO"));
+ hdd_enter_wowl(pHostapdAdapter, enable_magic_pkt,
+ enable_pattrn_byte_match);
+ break;
+ default:
+ hddLog(LOGE, "Invalid arg %d in WE_WOWL IOCTL", set_value);
+ ret = -EINVAL;
+ break;
+ }
+ break;
+ }
+ case QCSAP_PARAM_CAP_TSF:
+ {
+ ret = hdd_capture_tsf(pHostapdAdapter,
+ (uint32_t *)&set_value, 1);
break;
}
default:
@@ -2187,6 +2306,112 @@ static iw_softap_getparam(struct net_device *dev,
return ret;
}
+
+int
+static __iw_softap_setchar_getnone(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ int sub_cmd;
+ int ret = 0; /* success */
+ char *pBuffer = NULL;
+ hdd_adapter_t *pAdapter;
+ hdd_context_t *pHddCtx;
+ struct iw_point s_priv_data;
+
+ ENTER();
+
+ if (!capable(CAP_NET_ADMIN))
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ FL("permission check failed"));
+ return -EPERM;
+ }
+
+ pAdapter = (netdev_priv(dev));
+ pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
+ ret = wlan_hdd_validate_context(pHddCtx);
+ if (0 != ret)
+ {
+ return ret;
+ }
+
+ if (!pHddCtx->is_ap_mode_wow_supported)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "%s: Not supported",__func__);
+ return -ENOTSUPP;
+ }
+
+ /* helper function to get iwreq_data with compat handling. */
+ if (hdd_priv_get_data(&s_priv_data, wrqu))
+ {
+ return -EINVAL;
+ }
+
+ /* make sure all params are correctly passed to function */
+ if ((NULL == s_priv_data.pointer) || (0 == s_priv_data.length))
+ {
+ return -EINVAL;
+ }
+
+ sub_cmd = s_priv_data.flags;
+
+ /* ODD number is used for set, copy data using copy_from_user */
+ pBuffer = mem_alloc_copy_from_user_helper(s_priv_data.pointer,
+ s_priv_data.length);
+ if (NULL == pBuffer)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "mem_alloc_copy_from_user_helper fail");
+ return -ENOMEM;
+ }
+
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "%s: Received length %d", __func__, s_priv_data.length);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "%s: Received data %s", __func__, pBuffer);
+
+ switch(sub_cmd)
+ {
+ case WE_WOWL_ADD_PTRN:
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "ADD_PTRN");
+ ret = hdd_add_wowl_ptrn(pAdapter, pBuffer);
+ if (!ret)
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "Failed to add pattern :%d", ret);
+ break;
+ case WE_WOWL_DEL_PTRN:
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "DEL_PTRN");
+ ret = hdd_del_wowl_ptrn(pAdapter, pBuffer);
+ if (!ret)
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "Failed to del pattern :%d", ret);
+ break;
+ default:
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "ioctl not supported in SOFTAP");
+ ret = -EINVAL;
+ break;
+ }
+
+ kfree(pBuffer);
+ return ret;
+}
+
+int
+static iw_softap_setchar_getnone(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ int ret;
+
+ vos_ssr_protect(__func__);
+ ret = __iw_softap_setchar_getnone(dev, info, wrqu, extra);
+ vos_ssr_unprotect(__func__);
+
+ return ret;
+}
+
/* Usage:
BLACK_LIST = 0
WHITE_LIST = 1
@@ -3029,6 +3254,60 @@ static iw_softap_ap_stats(struct net_device *dev,
return ret;
}
+/**
+ * __iw_softap_get_three() - return three value to upper layer.
+ *
+ * @dev: pointer of net_device of this wireless card
+ * @info: meta data about Request sent
+ * @wrqu: include request info
+ * @extra: buf used for in/out
+ *
+ * Return: execute result
+ */
+static int __iw_softap_get_three(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ uint32_t *value = (uint32_t *)extra;
+ uint32_t sub_cmd = value[0];
+ int ret = 0; /* success */
+
+ hdd_adapter_t *padapter = WLAN_HDD_GET_PRIV_PTR(dev);
+
+ switch (sub_cmd) {
+ case QCSAP_IOCTL_GET_TSF:
+ ret = hdd_indicate_tsf(padapter, value, 3);
+ break;
+ default:
+ hddLog(LOGE, FL("Invalid getparam command %d"), sub_cmd);
+ break;
+ }
+ return ret;
+}
+
+
+/**
+ * iw_softap_get_three() - return three value to upper layer.
+ *
+ * @dev: pointer of net_device of this wireless card
+ * @info: meta data about Request sent
+ * @wrqu: include request info
+ * @extra: buf used for in/Output
+ *
+ * Return: execute result
+ */
+static int iw_softap_get_three(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ int ret;
+
+ vos_ssr_protect(__func__);
+ ret = __iw_softap_get_three(dev, info, wrqu, extra);
+ vos_ssr_unprotect(__func__);
+
+ return ret;
+}
static int __iw_softap_set_channel_range(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
@@ -4495,6 +4774,10 @@ static const struct iw_priv_args hostapd_private_args[] = {
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMcRate" },
{ QCSAP_PARAM_SET_PROXIMITY,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setProximity" },
+ { QCSAP_PARAM_CAP_TSF,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "cap_tsf" },
+ { QCSAP_PARAM_SET_WOWL,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wowl" },
{ QCSAP_IOCTL_GETPARAM,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getparam" },
@@ -4528,6 +4811,14 @@ static const struct iw_priv_args hostapd_private_args[] = {
IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 6 , 0, "disassoc_sta" },
{ QCSAP_IOCTL_AP_STATS, 0,
IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE, "ap_stats" },
+ /* handlers for main ioctl */
+ { QCSAP_IOCTL_PRIV_SET_NONE_GET_THREE_INT, 0,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, "" },
+#ifdef WLAN_FEATURE_TSF
+ { QCSAP_IOCTL_GET_TSF, 0,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
+ "get_tsf" },
+#endif
{ QCSAP_IOCTL_GET_STATS, 0,
IW_PRIV_TYPE_CHAR | QCSAP_MAX_STR_LEN, "getStats"},
{ QCSAP_IOCTL_CLR_STATS, 0, 0, "clearStats" },
@@ -4606,11 +4897,29 @@ static const struct iw_priv_args hostapd_private_args[] = {
IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
0,
"setTrafficMon" },
+ /* handlers for main ioctl */
+ { QCSAP_IOCTL_SET_CHAR_GET_NONE,
+ IW_PRIV_TYPE_CHAR| 512,
+ 0,
+ "" },
+
+ /* handlers for sub-ioctl */
+ { WE_WOWL_ADD_PTRN,
+ IW_PRIV_TYPE_CHAR| 512,
+ 0,
+ "wowlAddPtrn" },
+
+ { WE_WOWL_DEL_PTRN,
+ IW_PRIV_TYPE_CHAR| 512,
+ 0,
+ "wowlDelPtrn" },
};
static const iw_handler hostapd_private[] = {
[QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam, //set priv ioctl
- [QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam, //get priv ioctl
+ [QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam, //get priv ioctl
+ [QCSAP_IOCTL_SET_CHAR_GET_NONE - SIOCIWFIRSTPRIV] =
+ iw_softap_setchar_getnone,
[QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie, //get station genIE
[QCSAP_IOCTL_STOPBSS - SIOCIWFIRSTPRIV] = iw_softap_stopbss, // stop bss
[QCSAP_IOCTL_VERSION - SIOCIWFIRSTPRIV] = iw_softap_version, // get driver version
@@ -4619,6 +4928,7 @@ static const iw_handler hostapd_private[] = {
[QCSAP_IOCTL_ASSOC_STA_MACADDR - SIOCIWFIRSTPRIV] = iw_softap_getassoc_stamacaddr,
[QCSAP_IOCTL_DISASSOC_STA - SIOCIWFIRSTPRIV] = iw_softap_disassoc_sta,
[QCSAP_IOCTL_AP_STATS - SIOCIWFIRSTPRIV] = iw_softap_ap_stats,
+ [QCSAP_IOCTL_PRIV_SET_NONE_GET_THREE_INT - SIOCIWFIRSTPRIV] = iw_softap_get_three,
[QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_three_ints_getnone,
[QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_var_ints_getnone,
[QCSAP_IOCTL_SET_CHANNEL_RANGE - SIOCIWFIRSTPRIV] = iw_softap_set_channel_range,
@@ -4681,6 +4991,12 @@ void hdd_set_ap_ops( struct net_device *pWlanHostapdDev )
VOS_STATUS hdd_init_ap_mode( hdd_adapter_t *pAdapter, bool re_init)
{
hdd_hostapd_state_t * phostapdBuf;
+#ifdef DHCP_SERVER_OFFLOAD
+ hdd_dhcp_state_t *dhcp_status;
+#endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+ hdd_mdns_state_t *mdns_status;
+#endif /* MDNS_OFFLOAD */
struct net_device *dev = pAdapter->dev;
hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
VOS_STATUS status;
@@ -4697,8 +5013,27 @@ VOS_STATUS hdd_init_ap_mode( hdd_adapter_t *pAdapter, bool re_init)
}
ENTER();
- // Allocate the Wireless Extensions state structure
+
+#ifdef SAP_AUTH_OFFLOAD
+ if (pHddCtx->cfg_ini->enable_sap_auth_offload)
+ {
+ if (!hdd_set_sap_auth_offload(pAdapter, TRUE))
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ FL("SAP AUTH OFFLOAD is not enabled successfully, Don't start SAP"));
+ return VOS_STATUS_E_FAILURE;
+ }
+ }
+#endif
+
+ // Allocate the Wireless Extensions state structure
phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR( pAdapter );
+#ifdef DHCP_SERVER_OFFLOAD
+ dhcp_status = &pAdapter->dhcp_status;
+#endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+ mdns_status = &pAdapter->mdns_status;
+#endif /* MDNS_OFFLOAD */
spin_lock_init(&pAdapter->sta_hash_lock);
pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
@@ -4720,7 +5055,13 @@ VOS_STATUS hdd_init_ap_mode( hdd_adapter_t *pAdapter, bool re_init)
// Zero the memory. This zeros the profile structure.
memset(phostapdBuf, 0,sizeof(hdd_hostapd_state_t));
-
+#ifdef DHCP_SERVER_OFFLOAD
+ memset(dhcp_status, 0,sizeof(*dhcp_status));
+#endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+ memset(mdns_status, 0,sizeof(*mdns_status));
+#endif /* MDNS_OFFLOAD */
+
// Set up the pointer to the Wireless Extensions state structure
// NOP
status = hdd_set_hostapd(pAdapter);
@@ -4735,7 +5076,21 @@ VOS_STATUS hdd_init_ap_mode( hdd_adapter_t *pAdapter, bool re_init)
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: Hostapd HDD vos event init failed!!"));
return status;
}
-
+#ifdef DHCP_SERVER_OFFLOAD
+ status = vos_event_init(&dhcp_status->vos_event);
+ if (!VOS_IS_STATUS_SUCCESS(status)) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: Hostapd HDD vos event init failed!!"));
+ return status;
+ }
+#endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+ status = vos_event_init(&mdns_status->vos_event);
+ if (!VOS_IS_STATUS_SUCCESS(status)) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ ("Hostapd HDD vos event init failed!!"));
+ return status;
+ }
+#endif /* MDNS_OFFLOAD */
sema_init(&(WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->semWpsPBCOverlapInd, 1);
@@ -5009,3 +5364,41 @@ void hdd_sap_destroy_timers(hdd_adapter_t *adapter)
FL("Failed to Destroy HT20/40 timer"));
}
+
+/**
+ * hdd_force_scc_restart_sap - restart sap to forcer SCC
+ * @adapter: hdd ap adapter
+ *
+ * hdd_force_scc_restart_sap will choose station channel and will
+ * schedule work to restart the sap.
+ *
+ * Return - none
+ */
+void hdd_force_scc_restart_sap(hdd_adapter_t *adapter,
+ hdd_context_t *hdd_ctx, tANI_U8 channelId)
+{
+ if (!(adapter && (WLAN_HDD_SOFTAP == adapter->device_mode))) {
+ return;
+ }
+
+ hddLog(LOG1, FL("Current operation channel %d"),
+ adapter->sessionCtx.ap.operatingChannel);
+ hddLog(LOG1, FL("STA channel is %d"),
+ channelId);
+
+ vos_flush_work(
+ &hdd_ctx->sap_start_work);
+
+ hddLog(LOGE,
+ FL("Restarting SAP for force SCC "));
+
+ adapter->sessionCtx.ap.sapConfig.channel = channelId;
+
+ if (hdd_ctx->cfg_ini->sap_internal_restart) {
+ netif_tx_disable(adapter->dev);
+ schedule_work(&hdd_ctx->sap_start_work);
+ } else {
+ hdd_hostapd_stop(adapter->dev);
+ }
+ return;
+}
diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_main.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_main.c
index 668b61948f4..6dc22da0ec2 100644
--- a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_main.c
+++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_main.c
@@ -758,11 +758,6 @@ void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
/*New country doesn't support DFS */
sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
}
- else
- {
- /*New country Supports DFS as well resetting value back from .ini*/
- sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
- }
}
@@ -799,7 +794,7 @@ static int hdd_parse_setrmcenable_command(tANI_U8 *pValue, tANI_U8 *pRmcEnable)
/* getting the first argument which enables or disables RMC
* for input IP v4 address*/
- sscanf(inPtr, "%32s ", buf);
+ sscanf(inPtr, "%31s ", buf);
v = kstrtos32(buf, 10, &tempInt);
if ( v < 0)
{
@@ -848,7 +843,7 @@ static int hdd_parse_setrmcactionperiod_command(tANI_U8 *pValue,
/* getting the first argument which enables or disables RMC
* for input IP v4 address*/
- sscanf(inPtr, "%32s ", buf);
+ sscanf(inPtr, "%31s ", buf);
v = kstrtos32(buf, 10, &tempInt);
if ( v < 0)
{
@@ -906,7 +901,7 @@ static int hdd_parse_setrmcrate_command(tANI_U8 *pValue,
/*
* getting the first argument which sets multicast rate.
*/
- sscanf(inPtr, "%32s ", buf);
+ sscanf(inPtr, "%31s ", buf);
v = kstrtos32(buf, 10, &tempInt);
if ( v < 0)
{
@@ -2593,16 +2588,23 @@ hdd_parse_reassoc_v1(hdd_adapter_t *pAdapter, const char *command)
* @pAdapter: Adapter upon which the command was received
* @command: command that was received, ASCII command followed
* by binary data
+ * @total_len: Total length of the command received
*
* Return: 0 for success non-zero for failure
*/
static int
-hdd_parse_reassoc_v2(hdd_adapter_t *pAdapter, const char *command)
+hdd_parse_reassoc_v2(hdd_adapter_t *pAdapter, const char *command,
+ int total_len)
{
struct android_wifi_reassoc_params params;
tSirMacAddr bssid;
int ret;
+ if (total_len < sizeof(params) + 8) {
+ hddLog(LOGE, FL("Invalid command length"));
+ return -EINVAL;
+ }
+
/* The params are located after "REASSOC " */
memcpy(&params, command + 8, sizeof(params));
@@ -2626,11 +2628,12 @@ hdd_parse_reassoc_v2(hdd_adapter_t *pAdapter, const char *command)
*
* @pAdapter: Adapter upon which the command was received
* @command: command that was received
+ * @total_len: Total length of the command received
*
* Return: 0 for success non-zero for failure
*/
static int
-hdd_parse_reassoc(hdd_adapter_t *pAdapter, const char *command)
+hdd_parse_reassoc(hdd_adapter_t *pAdapter, const char *command, int total_len)
{
int ret;
@@ -2648,10 +2651,16 @@ hdd_parse_reassoc(hdd_adapter_t *pAdapter, const char *command)
* 1111111111222222
* 01234567890123456789012345
*/
+
+ if (total_len < 26) {
+ hddLog(LOGE, FL("Invalid command (total_len=%d)"), total_len);
+ return -EINVAL;
+ }
+
if (command[25])
ret = hdd_parse_reassoc_v1(pAdapter, command);
else
- ret = hdd_parse_reassoc_v2(pAdapter, command);
+ ret = hdd_parse_reassoc_v2(pAdapter, command, total_len);
return ret;
}
@@ -2759,6 +2768,55 @@ void hdd_FWStatisCB( VOS_STATUS status,
return;
}
+/*
+ *hdd_parse_setmaxtxpower_command() - HDD Parse MAXTXPOWER command
+ *@pValue Pointer to MAXTXPOWER command
+ *@pTxPower Pointer to tx power
+ *
+ *This function parses the MAXTXPOWER command passed in the format
+ * MAXTXPOWER<space>X(Tx power in dbm)
+ * For example input commands:
+ * 1) MAXTXPOWER -8 -> This is translated into set max TX power to -8 dbm
+ * 2) MAXTXPOWER -23 -> This is translated into set max TX power to -23 dbm
+ *
+ *return - 0 for success non-zero for failure
+ */
+static int hdd_parse_setmaxtxpower_command(unsigned char *pValue, int *pTxPower)
+{
+ unsigned char *inPtr = pValue;
+ int tempInt;
+ int v = 0;
+ *pTxPower = 0;
+
+ inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
+ /* no argument after the command */
+ if (NULL == inPtr)
+ return -EINVAL;
+ /* no space after the command */
+ else if (SPACE_ASCII_VALUE != *inPtr)
+ return -EINVAL;
+
+ /* removing empty spaces */
+ while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
+
+ /* no argument followed by spaces */
+ if ('\0' == *inPtr)
+ return 0;
+
+ v = kstrtos32(inPtr, 10, &tempInt);
+
+ /* Range checking for passed parameter */
+ if ((tempInt < HDD_MIN_TX_POWER) || (tempInt > HDD_MAX_TX_POWER))
+ return -EINVAL;
+
+ *pTxPower = tempInt;
+
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "SETMAXTXPOWER: %d", *pTxPower);
+
+ return 0;
+}
+
static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
{
int ret = 0;
@@ -2809,6 +2867,14 @@ static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra,
return ret;
}
+int hdd_drv_cmd_validate(tANI_U8 *command, int len)
+{
+ if (command[len] != ' ')
+ return -EINVAL;
+
+ return 0;
+}
+
static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
{
tHalHandle hHal;
@@ -2831,6 +2897,9 @@ static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
{
+ if (hdd_drv_cmd_validate(command, 23))
+ return -EINVAL;
+
value = value + 24;
temp = kstrtou32(value, 10, &val);
if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
@@ -2847,6 +2916,9 @@ static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
}
else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
{
+ if (hdd_drv_cmd_validate(command, 23))
+ return -EINVAL;
+
value = value + 24;
temp = kstrtou32(value, 10, &val);
if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
@@ -2863,6 +2935,9 @@ static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
}
else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
{
+ if (hdd_drv_cmd_validate(command, 24))
+ return -EINVAL;
+
value = value + 25;
temp = kstrtou32(value, 10, &val);
if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
@@ -2879,6 +2954,9 @@ static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
}
else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
{
+ if (hdd_drv_cmd_validate(command, 24))
+ return -EINVAL;
+
value = value + 25;
temp = kstrtou32(value, 10, &val);
if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
@@ -2895,6 +2973,9 @@ static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
}
else if (strncmp(command, "SETDWELLTIME", 12) == 0)
{
+ if (hdd_drv_cmd_validate(command, 12))
+ return -EINVAL;
+
value = value + 13;
temp = kstrtou32(value, 10, &val);
if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
@@ -3204,6 +3285,10 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
{
tANI_U8 *ptr = command ;
+ ret = hdd_drv_cmd_validate(command, 7);
+ if (ret)
+ goto exit;
+
/* Change band request received */
/* First 8 bytes will have "SETBAND " and
@@ -3222,12 +3307,22 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
else if(strncmp(command, "SETWMMPS", 8) == 0)
{
tANI_U8 *ptr = command;
+
+ ret = hdd_drv_cmd_validate(command, 8);
+ if (ret)
+ goto exit;
+
ret = hdd_wmmps_helper(pAdapter, ptr);
}
else if(strncmp(command, "TDLSSCAN", 8) == 0)
{
tANI_U8 *ptr = command;
+
+ ret = hdd_drv_cmd_validate(command, 8);
+ if (ret)
+ goto exit;
+
ret = hdd_set_tdls_scan_type(pAdapter, ptr);
}
@@ -3235,6 +3330,10 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
{
char *country_code;
+ ret = hdd_drv_cmd_validate(command, 7);
+ if (ret)
+ goto exit;
+
country_code = command + 8;
INIT_COMPLETION(pAdapter->change_country_code);
@@ -3281,7 +3380,13 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
{
int suspend = 0;
- tANI_U8 *ptr = (tANI_U8*)command + 15;
+ tANI_U8 *ptr;
+
+ ret = hdd_drv_cmd_validate(command, 14);
+ if (ret)
+ goto exit;
+
+ ptr = (tANI_U8*)command + 15;
suspend = *ptr - '0';
MTRACE(vos_trace(VOS_MODULE_ID_HDD,
@@ -3297,6 +3402,10 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
eHalStatus status = eHAL_STATUS_SUCCESS;
+ ret = hdd_drv_cmd_validate(command, 14);
+ if (ret)
+ goto exit;
+
/* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
value = value + 15;
@@ -3375,6 +3484,10 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
tANI_U8 roamScanPeriod = 0;
tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
+ ret = hdd_drv_cmd_validate(command, 17);
+ if (ret)
+ goto exit;
+
/* input refresh period is in terms of seconds */
/* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
value = value + 18;
@@ -3442,6 +3555,10 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
tANI_U8 roamScanRefreshPeriod = 0;
tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
+ ret = hdd_drv_cmd_validate(command, 24);
+ if (ret)
+ goto exit;
+
/* input refresh period is in terms of seconds */
/* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
value = value + 25;
@@ -3505,6 +3622,10 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
tANI_U8 *value = command;
tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
+ ret = hdd_drv_cmd_validate(command, SIZE_OF_SETROAMMODE);
+ if (ret)
+ goto exit;
+
/* Move pointer to ahead of SETROAMMODE<delimiter> */
value = value + SIZE_OF_SETROAMMODE + 1;
@@ -3582,6 +3703,10 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
tANI_U8 *value = command;
tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
+ ret = hdd_drv_cmd_validate(command, 12);
+ if (ret)
+ goto exit;
+
/* Move pointer to ahead of SETROAMDELTA<delimiter> */
value = value + 13;
/* Convert the value from ascii to integer */
@@ -3830,6 +3955,10 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
tANI_U8 *value = command;
tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
+ ret = hdd_drv_cmd_validate(command, 25);
+ if (ret)
+ goto exit;
+
/* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
value = value + 26;
/* Convert the value from ascii to integer */
@@ -4014,6 +4143,10 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
tANI_U8 *value = command;
tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
+ ret = hdd_drv_cmd_validate(command, 18);
+ if (ret)
+ goto exit;
+
/* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
value = value + 19;
/* Convert the value from ascii to integer */
@@ -4071,6 +4204,10 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
tANI_U8 *value = command;
tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
+ ret = hdd_drv_cmd_validate(command, 15);
+ if (ret)
+ goto exit;
+
/* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
value = value + 16;
/* Convert the value from ascii to integer */
@@ -4128,6 +4265,10 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
tANI_U8 *value = command;
tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
+ ret = hdd_drv_cmd_validate(command, 16);
+ if (ret)
+ goto exit;
+
/* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
value = value + 17;
/* Convert the value from ascii to integer */
@@ -4184,6 +4325,10 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
tANI_U8 *value = command;
tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
+ ret = hdd_drv_cmd_validate(command, 14);
+ if (ret)
+ goto exit;
+
/* Move pointer to ahead of SETSCANNPROBES<delimiter> */
value = value + 15;
/* Convert the value from ascii to integer */
@@ -4238,6 +4383,10 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
tANI_U8 *value = command;
tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
+ ret = hdd_drv_cmd_validate(command, 19);
+ if (ret)
+ goto exit;
+
/* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
/* input value is in units of msec */
value = value + 20;
@@ -4292,7 +4441,11 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
}
else if (strncmp(command, "REASSOC", 7) == 0)
{
- ret = hdd_parse_reassoc(pAdapter, command);
+ ret = hdd_drv_cmd_validate(command, 7);
+ if (ret)
+ goto exit;
+
+ ret = hdd_parse_reassoc(pAdapter, command, priv_data.total_len);
if (!ret)
goto exit;
}
@@ -4301,6 +4454,10 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
tANI_U8 *value = command;
tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
+ ret = hdd_drv_cmd_validate(command, 10);
+ if (ret)
+ goto exit;
+
/* Move pointer to ahead of SETWESMODE<delimiter> */
value = value + 11;
/* Convert the value from ascii to integer */
@@ -4356,6 +4513,10 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
tANI_U8 *value = command;
tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
+ ret = hdd_drv_cmd_validate(command, 11);
+ if (ret)
+ goto exit;
+
/* Move pointer to ahead of SETFASTROAM<delimiter> */
value = value + 12;
/* Convert the value from ascii to integer */
@@ -4397,6 +4558,10 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
tANI_U8 *value = command;
tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
+ ret = hdd_drv_cmd_validate(command, 17);
+ if (ret)
+ goto exit;
+
/* Move pointer to ahead of SETFASTROAM<delimiter> */
value = value + 18;
/* Convert the value from ascii to integer */
@@ -4436,6 +4601,10 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
tANI_U8 *value = command;
tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
+ ret = hdd_drv_cmd_validate(command, 14);
+ if (ret)
+ goto exit;
+
/* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
value = value + 15;
/* Convert the value from ascii to integer */
@@ -4499,6 +4668,10 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
tANI_U8 *value = command;
tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
+ ret = hdd_drv_cmd_validate(command, 10);
+ if (ret)
+ goto exit;
+
/* Check if the features OKC/ESE/11R are supported simultaneously,
then this operation is not permitted (return FAILURE) */
if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
@@ -4550,6 +4723,10 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
tANI_U8 *value = command;
tANI_BOOLEAN roamScanControl = 0;
+ ret = hdd_drv_cmd_validate(command, 18);
+ if (ret)
+ goto exit;
+
/* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
value = value + 19;
/* Convert the value from ascii to integer */
@@ -4583,6 +4760,10 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
tANI_U8 *value = command;
tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
+ ret = hdd_drv_cmd_validate(command, 10);
+ if (ret)
+ goto exit;
+
/* Check if the features OKC/ESE/11R are supported simultaneously,
then this operation is not permitted (return FAILURE) */
if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
@@ -4652,6 +4833,10 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
tANI_U8 filterType = 0;
tANI_U8 *value = command;
+ ret = hdd_drv_cmd_validate(command, 21);
+ if (ret)
+ goto exit;
+
/* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
value = value + 22;
@@ -4684,6 +4869,10 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
char *dhcpPhase;
int ret;
+ ret = hdd_drv_cmd_validate(command, 10);
+ if (ret)
+ goto exit;
+
dhcpPhase = command + 11;
if ('1' == *dhcpPhase)
{
@@ -4750,6 +4939,11 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
{
tANI_U8 filterType = 0;
tANI_U8 *value;
+
+ ret = hdd_drv_cmd_validate(command, 8);
+ if (ret)
+ goto exit;
+
value = command + 9;
/* Convert the value from ascii to integer */
@@ -4795,6 +4989,10 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
tSirRateUpdateInd *rateUpdate;
eHalStatus status;
+ ret = hdd_drv_cmd_validate(command, 9);
+ if (ret)
+ goto exit;
+
/* Only valid for SAP mode */
if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
{
@@ -4838,6 +5036,41 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
goto exit;
}
}
+ else if (strncmp(command, "MAXTXPOWER", 10) == 0)
+ {
+ int status;
+ int txPower;
+ eHalStatus smeStatus;
+ tANI_U8 *value = command;
+ tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
+ tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
+
+ status = hdd_parse_setmaxtxpower_command(value, &txPower);
+ if (status)
+ {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "Invalid MAXTXPOWER command ");
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ hddLog(VOS_TRACE_LEVEL_INFO, "max tx power %d selfMac: "
+ MAC_ADDRESS_STR " bssId: " MAC_ADDRESS_STR " ",
+ txPower, MAC_ADDR_ARRAY(selfMac),
+ MAC_ADDR_ARRAY(bssid));
+ smeStatus = sme_SetMaxTxPower((tHalHandle)(pHddCtx->hHal),
+ bssid, selfMac, txPower) ;
+ if( smeStatus != eHAL_STATUS_SUCCESS )
+ {
+ hddLog(VOS_TRACE_LEVEL_ERROR, "%s:Set max tx power failed",
+ __func__);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ hddLog(VOS_TRACE_LEVEL_INFO, "%s: Set max tx power success",
+ __func__);
+ }
#ifdef FEATURE_WLAN_BATCH_SCAN
else if (strncmp(command, "WLS_BATCHING", 12) == 0)
{
@@ -5587,6 +5820,10 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
tAniTrafStrmMetrics tsmMetrics;
pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
+ ret = hdd_drv_cmd_validate(command, 11);
+ if (ret)
+ goto exit;
+
/* if not associated, return error */
if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
{
@@ -5796,6 +6033,11 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
tANI_U8 *value = command;
int set_value;
+
+ ret = hdd_drv_cmd_validate(command, 26);
+ if (ret)
+ goto exit;
+
/* Move pointer to ahead of TDLSOFFCH*/
value += 26;
if (!(sscanf(value, "%d", &set_value))) {
@@ -5818,6 +6060,11 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
} else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
tANI_U8 *value = command;
int set_value;
+
+ ret = hdd_drv_cmd_validate(command, 18);
+ if (ret)
+ goto exit;
+
/* Move pointer to ahead of tdlsoffchnmode*/
value += 18;
ret = sscanf(value, "%d", &set_value);
@@ -5839,6 +6086,11 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
} else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
tANI_U8 *value = command;
int set_value;
+
+ ret = hdd_drv_cmd_validate(command, 14);
+ if (ret)
+ goto exit;
+
/* Move pointer to ahead of TDLSOFFCH*/
value += 14;
ret = sscanf(value, "%d", &set_value);
@@ -5869,8 +6121,13 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
fwStatsContext_t fwStatsCtx;
tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
tANI_U8 *ptr = command;
- int stats = *(ptr + 11) - '0';
+ int stats;
+ ret = hdd_drv_cmd_validate(command, 10);
+ if (ret)
+ goto exit;
+
+ stats = *(ptr + 11) - '0';
hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
if (!IS_FEATURE_FW_STATS_ENABLE)
{
@@ -5964,6 +6221,10 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
}
else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
{
+ ret = hdd_drv_cmd_validate(command, 15);
+ if (ret)
+ goto exit;
+
/*
* this command wld be called by user-space when it detects WLAN
* ON after airplane mode is set. When APM is set, WLAN turns off.
@@ -5977,6 +6238,10 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
}
else if (strncasecmp(command, "DISABLE_CA_EVENT", 16) == 0)
{
+ ret = hdd_drv_cmd_validate(command, 16);
+ if (ret)
+ goto exit;
+
ret = hdd_enable_disable_ca_event(pHddCtx, command, 16);
}
else {
@@ -8828,13 +9093,14 @@ hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
if(VOS_STATUS_SUCCESS == status)
{
wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
-
//Initialize the WoWL service
if(!hdd_init_wowl(pAdapter))
{
hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
goto err_free_netdev;
}
+ //Initialize the TSF capture data
+ wlan_hdd_tsf_init(pAdapter);
}
return pAdapter;
@@ -8970,6 +9236,18 @@ void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
}
}
+VOS_STATUS hdd_cleanup_ap_events(hdd_adapter_t *adapter)
+{
+#ifdef DHCP_SERVER_OFFLOAD
+ vos_event_destroy(&adapter->dhcp_status.vos_event);
+#endif
+#ifdef MDNS_OFFLOAD
+ vos_event_destroy(&adapter->mdns_status.vos_event);
+#endif
+ return VOS_STATUS_SUCCESS;
+}
+
+
VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
const v_BOOL_t bCloseSession )
{
@@ -9014,6 +9292,13 @@ VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
if( hdd_connIsConnected(pstation) ||
(pstation->conn_info.connState == eConnectionState_Connecting) )
{
+ /*
+ * Indicate sme of disconnect so that in progress connection
+ * or preauth can be aborted.
+ */
+ sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
+ pAdapter->sessionId);
+ INIT_COMPLETION(pAdapter->disconnect_comp_var);
if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
halStatus = sme_RoamDisconnect(pHddCtx->hHal,
pAdapter->sessionId,
@@ -9140,6 +9425,7 @@ VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
}
//Any softap specific cleanup here...
+ hdd_cleanup_ap_events(pAdapter);
if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
while (pAdapter->is_roc_inprogress) {
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
@@ -9160,6 +9446,10 @@ VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
vos_flush_delayed_work(&pAdapter->roc_work);
}
+#ifdef SAP_AUTH_OFFLOAD
+ if (pHddCtx->cfg_ini->enable_sap_auth_offload)
+ hdd_set_sap_auth_offload(pAdapter, FALSE);
+#endif
mutex_lock(&pHddCtx->sap_lock);
if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
{
@@ -9297,6 +9587,18 @@ static void wlan_hdd_restart_sap(hdd_adapter_t *ap_adapter)
set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
wlan_hdd_incr_active_session(pHddCtx, ap_adapter->device_mode);
pHostapdState->bCommit = TRUE;
+ if (!VOS_IS_STATUS_SUCCESS(hdd_dhcp_mdns_offload(ap_adapter))) {
+ hddLog(VOS_TRACE_LEVEL_ERROR, FL("DHCP/MDNS offload Failed!!"));
+ vos_event_reset(&pHostapdState->vosEvent);
+ if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
+ vos_status = vos_wait_single_event(&pHostapdState->vosEvent,
+ 10000);
+ if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
+ hddLog(LOGE, FL("SAP Stop Failed"));
+ goto end;
+ }
+ }
+ }
}
end:
mutex_unlock(&pHddCtx->sap_lock);
@@ -9336,6 +9638,8 @@ static void __hdd_sap_restart_handle(struct work_struct *work)
wlan_hdd_restart_sap(sap_adapter);
hdd_change_ch_avoidance_status(hdd_ctx, false);
}
+ if (hdd_ctx->cfg_ini->enable_sap_auth_offload)
+ wlan_hdd_restart_sap(sap_adapter);
}
/**
@@ -11900,14 +12204,11 @@ int hdd_wlan_startup(struct device *dev )
/*
* cfg80211: Initialization ...
*/
- if (VOS_FTM_MODE != hdd_get_conparam())
+ if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
{
- if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
- {
- hddLog(VOS_TRACE_LEVEL_FATAL,
- "%s: wlan_hdd_cfg80211_init return failure", __func__);
- goto err_config;
- }
+ hddLog(VOS_TRACE_LEVEL_FATAL,
+ "%s: wlan_hdd_cfg80211_init return failure", __func__);
+ goto err_config;
}
// Update VOS trace levels based upon the cfg.ini
@@ -12453,7 +12754,7 @@ int hdd_wlan_startup(struct device *dev )
{
hddLog(VOS_TRACE_LEVEL_FATAL,
"%s: oem_activate_service failed", __func__);
- goto err_reg_netdev;
+ goto err_btc_activate_service;
}
#endif
@@ -12462,7 +12763,7 @@ int hdd_wlan_startup(struct device *dev )
if(ptt_sock_activate_svc(pHddCtx) != 0)
{
hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
- goto err_reg_netdev;
+ goto err_oem_activate_service;
}
#endif
@@ -12470,7 +12771,7 @@ int hdd_wlan_startup(struct device *dev )
if (hdd_open_cesium_nl_sock() < 0)
{
hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_open_cesium_nl_sock failed", __func__);
- goto err_reg_netdev;
+ goto err_ptt_sock_activate_svc;
}
#endif
@@ -12485,7 +12786,7 @@ int hdd_wlan_startup(struct device *dev )
{
hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
" failed", __func__);
- goto err_reg_netdev;
+ goto err_open_cesium_nl_sock;
}
//TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
//EAPOL and DHCP
@@ -12511,6 +12812,13 @@ int hdd_wlan_startup(struct device *dev )
#endif
+#ifdef SAP_AUTH_OFFLOAD
+ if (!sme_IsFeatureSupportedByFW(SAP_OFFLOADS))
+ {
+ hddLog(VOS_TRACE_LEVEL_INFO, FL(" SAP AUTH OFFLOAD not supp by FW"));
+ pHddCtx->cfg_ini->enable_sap_auth_offload = 0;
+ }
+#endif
if (vos_is_multicast_logging())
wlan_logging_set_log_level();
@@ -12571,7 +12879,7 @@ int hdd_wlan_startup(struct device *dev )
vos_wdthread_init_timer_work(vos_process_wd_timer);
/* Initialize the timer to detect thread stuck issues */
vos_thread_stuck_timer_init(
- &((VosContextType*)pVosContext)->vosWatchdog);
+ &((VosContextType*)pVosContext)->vosWatchdog);
}
//Register the traffic monitor timer now
@@ -12618,6 +12926,8 @@ int hdd_wlan_startup(struct device *dev )
}
#endif
+ vos_mem_set((uint8_t *)&pHddCtx->bad_sta, HDD_MAX_STA_COUNT, 0);
+
// Register IPv4 notifier to notify if any change in IP
// So that we can reconfigure the offload parameters
pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
@@ -12634,8 +12944,36 @@ int hdd_wlan_startup(struct device *dev )
memdump_init();
hdd_dp_util_send_rps_ind(pHddCtx);
+ pHddCtx->is_ap_mode_wow_supported =
+ sme_IsFeatureSupportedByFW(SAP_MODE_WOW);
+
+ pHddCtx->is_fatal_event_log_sup =
+ sme_IsFeatureSupportedByFW(FATAL_EVENT_LOGGING);
+ hddLog(VOS_TRACE_LEVEL_INFO, FL("FATAL_EVENT_LOGGING: %d"),
+ pHddCtx->is_fatal_event_log_sup);
+
+ hdd_assoc_registerFwdEapolCB(pVosContext);
+
goto success;
+err_open_cesium_nl_sock:
+#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
+ hdd_close_cesium_nl_sock();
+#endif
+
+err_ptt_sock_activate_svc:
+#ifdef PTT_SOCK_SVC_ENABLE
+ ptt_sock_deactivate_svc(pHddCtx);
+#endif
+
+err_oem_activate_service:
+#ifdef FEATURE_OEM_DATA_SUPPORT
+ oem_deactivate_service();
+#endif
+
+err_btc_activate_service:
+ btc_deactivate_service();
+
err_reg_netdev:
unregister_netdevice_notifier(&hdd_netdev_notifier);
@@ -12764,11 +13102,11 @@ static int hdd_driver_init( void)
#ifdef HAVE_WCNSS_CAL_DOWNLOAD
/* wait until WCNSS driver downloads NV */
- while (!wcnss_device_ready() && 5 >= ++max_retries) {
+ while (!wcnss_device_ready() && 10 >= ++max_retries) {
msleep(1000);
}
- if (max_retries >= 5) {
+ if (max_retries >= 10) {
hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
vos_wake_lock_destroy(&wlan_wake_lock);
#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
@@ -13380,9 +13718,13 @@ v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
return TRUE;
}
hddLog( LOGE, "%s: do not allow APPS power collapse-"
- "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
- __func__, pmcState, scanRspPending, inMiddleOfRoaming );
- return FALSE;
+ "pmcState = %d scanRspPending = %d "
+ "inMiddleOfRoaming = %d connected = %d",
+ __func__, pmcState, scanRspPending,
+ inMiddleOfRoaming, hdd_connIsConnected(
+ WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )));
+ wlan_hdd_get_tdls_stats(pAdapter);
+ return FALSE;
}
}
status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
@@ -13996,7 +14338,7 @@ int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
*/
if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
{
- status = wait_for_completion_interruptible_timeout(
+ status = wait_for_completion_timeout(
&pScanInfo->abortscan_event_var,
msecs_to_jiffies(5000));
if (0 >= status)
@@ -14843,10 +15185,1464 @@ void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter)
init_completion(&pAdapter->hdd_set_batch_scan_req_var);
init_completion(&pAdapter->hdd_get_batch_scan_req_var);
#endif
+ init_completion(&pAdapter->wlan_suspend_comp_var);
return;
}
+#ifdef MDNS_OFFLOAD
+
+/**
+ * hdd_mdns_enable_offload_done() - mdns enable offload response api
+ * @padapter: holds adapter
+ * @status: response status
+ *
+ * Return - None
+ */
+void hdd_mdns_enable_offload_done(void *padapter, VOS_STATUS status)
+{
+ hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
+
+ ENTER();
+
+ if (NULL == adapter)
+ {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ "%s: adapter is NULL",__func__);
+ return;
+ }
+
+ adapter->mdns_status.mdns_enable_status = status;
+ vos_event_set(&adapter->mdns_status.vos_event);
+ return;
+}
+
+/**
+ * hdd_mdns_fqdn_offload_done() - mdns fqdn offload response api
+ * @padapter: holds adapter
+ * @status: responce status
+ *
+ * Return - None
+ */
+void hdd_mdns_fqdn_offload_done(void *padapter, VOS_STATUS status)
+{
+ hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
+
+ ENTER();
+
+ if (NULL == adapter)
+ {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ "%s: adapter is NULL",__func__);
+ return;
+ }
+
+ adapter->mdns_status.mdns_fqdn_status = status;
+ return;
+}
+
+/**
+ * hdd_mdns_resp_offload_done() - mdns resp offload response api
+ * @padapter: holds adapter
+ * @status: responce status
+ *
+ * Return - None
+ */
+void hdd_mdns_resp_offload_done(void *padapter, VOS_STATUS status)
+{
+ hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
+
+ ENTER();
+
+ if (NULL == adapter)
+ {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ "%s: adapter is NULL",__func__);
+ return;
+ }
+
+ adapter->mdns_status.mdns_resp_status = status;
+ return;
+}
+
+/**
+ * wlan_hdd_mdns_process_response_dname() - Process mDNS domain name
+ * @response: Pointer to a struct hdd_mdns_resp_info
+ * @resp_info: Pointer to a struct tSirMDNSResponseInfo
+ *
+ * This function will pack the whole domain name without compression. It will
+ * add the leading len for each field and add zero length octet to terminate
+ * the domain name.
+ *
+ * Return: Return boolean. TRUE for success, FALSE for fail.
+ */
+static bool
+wlan_hdd_mdns_process_response_dname(struct hdd_mdns_resp_info *response,
+ sir_mdns_resp_info resp_info)
+{
+ uint8_t num;
+ uint16_t idx;
+ uint8_t len = 0;
+
+ if ((response == NULL) || (response->data == NULL) ||
+ (response->offset == NULL)) {
+ hddLog(LOGE, FL("Either data or offset in response is NULL!"));
+ return FALSE;
+ }
+
+ if ((resp_info == NULL) ||
+ (resp_info->resp_len >= MAX_MDNS_RESP_LEN)) {
+ hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
+ return FALSE;
+ }
+
+ for (num = 0; num < response->num_entries; num++) {
+ response->offset[num] =
+ resp_info->resp_len + MDNS_HEADER_LEN;
+ idx = num * MAX_LEN_DOMAINNAME_FIELD;
+ len = strlen((char *)&response->data[idx]);
+ if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
+ hddLog(LOGE, FL("resp_len exceeds %d!"),
+ MAX_MDNS_RESP_LEN);
+ return FALSE;
+ }
+ resp_info->resp_data[resp_info->resp_len] = len;
+ resp_info->resp_len++;
+ vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
+ &response->data[idx], len);
+ resp_info->resp_len += len;
+ }
+
+ /* The domain name terminates with the zero length octet */
+ if (num == response->num_entries) {
+ if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
+ hddLog(LOGE, FL("resp_len exceeds %d!"),
+ MAX_MDNS_RESP_LEN);
+ return FALSE;
+ }
+ resp_info->resp_data[resp_info->resp_len] = 0;
+ resp_info->resp_len++;
+ }
+
+ return TRUE;
+}
+
+/**
+ * wlan_hdd_mdns_format_response_u16() - Form uint16_t response data
+ * @value: The uint16_t value is formed to the struct tSirMDNSResponseInfo
+ * @resp_info: Pointer to a struct tSirMDNSResponseInfo
+ *
+ * Return: None
+ */
+static void wlan_hdd_mdns_format_response_u16(uint16_t value,
+ sir_mdns_resp_info resp_info)
+{
+ uint8_t val_u8;
+
+ if ((resp_info == NULL) || (resp_info->resp_data == NULL))
+ return;
+ val_u8 = (value & 0xff00) >> 8;
+ resp_info->resp_data[resp_info->resp_len++] = val_u8;
+ val_u8 = value & 0xff;
+ resp_info->resp_data[resp_info->resp_len++] = val_u8;
+}
+
+/**
+ * wlan_hdd_mdns_format_response_u32() - Form uint32_t response data
+ * @value: The uint32_t value is formed to the struct tSirMDNSResponseInfo
+ * @resp_info: Pointer to a struct tSirMDNSResponseInfo
+ *
+ * Return: None
+ */
+static void wlan_hdd_mdns_format_response_u32(uint32_t value,
+ sir_mdns_resp_info resp_info)
+{
+ uint8_t val_u8;
+
+ if ((resp_info == NULL) || (resp_info->resp_data == NULL))
+ return;
+ val_u8 = (value & 0xff000000) >> 24;
+ resp_info->resp_data[resp_info->resp_len++] = val_u8;
+ val_u8 = (value & 0xff0000) >> 16;
+ resp_info->resp_data[resp_info->resp_len++] = val_u8;
+ val_u8 = (value & 0xff00) >> 8;
+ resp_info->resp_data[resp_info->resp_len++] = val_u8;
+ val_u8 = value & 0xff;
+ resp_info->resp_data[resp_info->resp_len++] = val_u8;
+}
+
+/**
+ * wlan_hdd_mdns_process_response_misc() - Process misc info in mDNS response
+ * @resp_type: Response type for mDNS
+ * @resp_info: Pointer to a struct tSirMDNSResponseInfo
+ *
+ * This function will pack the response type, class and TTL (Time To Live).
+ *
+ * Return: Return boolean. TRUE for success, FALSE for fail.
+ */
+static bool wlan_hdd_mdns_process_response_misc(uint16_t resp_type,
+ sir_mdns_resp_info resp_info)
+{
+ uint16_t len;
+
+ if (resp_info == NULL) {
+ hddLog(LOGE, FL("resp_info is NULL!"));
+ return FALSE;
+ }
+
+ len = resp_info->resp_len + (2 * sizeof(uint16_t) + sizeof(uint32_t));
+ if (len >= MAX_MDNS_RESP_LEN) {
+ hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
+ return FALSE;
+ }
+
+ /* Fill Type, Class, TTL */
+ wlan_hdd_mdns_format_response_u16(resp_type, resp_info);
+ wlan_hdd_mdns_format_response_u16(MDNS_CLASS, resp_info);
+ wlan_hdd_mdns_format_response_u32(MDNS_TTL, resp_info);
+
+ return TRUE;
+}
+
+/**
+ * wlan_hdd_mdns_compress_data() - Compress the domain name in mDNS response
+ * @resp_info: Pointer to a struct tSirMDNSResponseInfo
+ * @response_dst: The response which domain name is compressed.
+ * @response_src: The response which domain name is matched with response_dst.
+ * Its offset is used for data compression.
+ * @num_matched: The number of matched entries between response_dst and
+ * response_src
+ *
+ * This function will form the different fields of domain name in response_dst
+ * if any. Then use the offset of the matched domain name in response_src to
+ * compress the matched domain name.
+ *
+ * Return: Return boolean. TRUE for success, FALSE for fail.
+ */
+static bool
+wlan_hdd_mdns_compress_data(sir_mdns_resp_info resp_info,
+ struct hdd_mdns_resp_info *response_dst,
+ struct hdd_mdns_resp_info *response_src,
+ uint8_t num_matched)
+{
+ uint8_t num, num_diff;
+ uint16_t value, idx;
+ uint8_t len = 0;
+
+ if ((response_src == NULL) || (response_dst == NULL) ||
+ (resp_info == NULL)) {
+ hddLog(LOGE, FL("response info is NULL!"));
+ return FALSE;
+ }
+
+ if (response_dst->num_entries < num_matched) {
+ hddLog(LOGE, FL("num_entries is less than num_matched!"));
+ return FALSE;
+ }
+
+ if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
+ hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
+ return FALSE;
+ }
+
+ num_diff = response_dst->num_entries - num_matched;
+ if ((num_diff > 0) && (response_dst->data == NULL)) {
+ hddLog(LOGE, FL("response_dst->data is NULL!"));
+ return FALSE;
+ }
+
+ /*
+ * Handle the unmatched string at the beginning
+ * Store the length of octets and the octets
+ */
+ for (num = 0; num < num_diff; num++) {
+ response_dst->offset[num] =
+ resp_info->resp_len + MDNS_HEADER_LEN;
+ idx = num * MAX_LEN_DOMAINNAME_FIELD;
+ len = strlen((char *)&response_dst->data[idx]);
+ if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
+ hddLog(LOGE, FL("resp_len exceeds %d!"),
+ MAX_MDNS_RESP_LEN);
+ return FALSE;
+ }
+ resp_info->resp_data[resp_info->resp_len] = len;
+ resp_info->resp_len++;
+ vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
+ &response_dst->data[idx], len);
+ resp_info->resp_len += len;
+ }
+ /*
+ * Handle the matched string from the end
+ * Just keep the offset and mask the leading two bit
+ */
+ if (response_src->num_entries >= num_matched) {
+ num_diff = response_src->num_entries - num_matched;
+ value = response_src->offset[num_diff];
+ if (value > 0) {
+ value |= 0xc000;
+ if ((resp_info->resp_len + sizeof(uint16_t)) >=
+ MAX_MDNS_RESP_LEN) {
+ hddLog(LOGE, FL("resp_len exceeds %d!"),
+ MAX_MDNS_RESP_LEN);
+ return FALSE;
+ }
+ wlan_hdd_mdns_format_response_u16(value, resp_info);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/**
+ * wlan_hdd_mdns_reset_response() - Reset the response info
+ * @response: The response which info is reset.
+ *
+ * Return: None
+ */
+static void wlan_hdd_mdns_reset_response(struct hdd_mdns_resp_info *response)
+{
+ if (response == NULL)
+ return;
+ response->num_entries = 0;
+ response->data = NULL;
+ response->offset = NULL;
+}
+
+/**
+ * wlan_hdd_mdns_init_response() - Initialize the response info
+ * @response: The response which info is initiatized.
+ * @resp_dname: The domain name string which might be tokenized.
+ *
+ * This function will allocate the memory for both response->data and
+ * response->offset. Besides, it will also tokenize the domain name to some
+ * entries and fill response->num_entries with the num of entries.
+ *
+ * Return: Return boolean. TRUE for success, FALSE for fail.
+ */
+static bool wlan_hdd_mdns_init_response(struct hdd_mdns_resp_info *response,
+ uint8_t *resp_dname, char separator)
+{
+ uint16_t size;
+
+ if ((resp_dname == NULL) || (response == NULL)) {
+ hddLog(LOGE, FL("resp_dname or response is NULL!"));
+ return FALSE;
+ }
+
+ size = MAX_NUM_FIELD_DOMAINNAME * MAX_LEN_DOMAINNAME_FIELD;
+ response->data = vos_mem_malloc(size);
+ if (response->data) {
+ vos_mem_zero(response->data, size);
+ if (VOS_STATUS_SUCCESS !=
+ hdd_string_to_string_array((char *)resp_dname,
+ response->data,
+ separator,
+ &response->num_entries,
+ MAX_NUM_FIELD_DOMAINNAME,
+ MAX_LEN_DOMAINNAME_FIELD)) {
+ hddLog(LOGE, FL("hdd_string_to_string_array fail!"));
+ goto err_init_resp;
+ }
+
+ if ((response->num_entries > 0) &&
+ (strlen((char *)&response->data[0]) > 0)) {
+ size = sizeof(uint16_t) * response->num_entries;
+ response->offset = vos_mem_malloc(size);
+ if (response->offset) {
+ vos_mem_zero(response->offset, size);
+ return TRUE;
+ }
+ }
+ }
+
+err_init_resp:
+ if (response->data)
+ vos_mem_free(response->data);
+ wlan_hdd_mdns_reset_response(response);
+ return FALSE;
+}
+
+/**
+ * wlan_hdd_mdns_find_entries_from_end() - Find the matched entries
+ * @response1: The response info is used to be compared.
+ * @response2: The response info is used to be compared.
+ *
+ * This function will find the matched entries from the end.
+ *
+ * Return: Return the number of the matched entries.
+ */
+static uint8_t
+wlan_hdd_mdns_find_entries_from_end(struct hdd_mdns_resp_info *response1,
+ struct hdd_mdns_resp_info *response2)
+{
+ uint8_t min, len1, i;
+ uint16_t num1, num2;
+ uint8_t num_matched = 0;
+
+ min = VOS_MIN(response1->num_entries, response2->num_entries);
+
+ for (i = 1; i <= min; i++) {
+ num1 = (response1->num_entries - i);
+ num1 *= MAX_LEN_DOMAINNAME_FIELD;
+ num2 = (response2->num_entries - i);
+ num2 *= MAX_LEN_DOMAINNAME_FIELD;
+ len1 = strlen((char *)&response1->data[num1]);
+
+ if ((len1 == 0) ||
+ (len1 != strlen((char *)&response2->data[num2])))
+ break;
+ if (memcmp(&response1->data[num1],
+ &response2->data[num2], len1))
+ break;
+ else
+ num_matched++;
+ }
+
+ return num_matched;
+}
+
+/**
+ * wlan_hdd_mdns_find_max() - Find the maximum number of the matched entries
+ * @matchedlist: Pointer to the array of struct hdd_mdns_resp_matched
+ * @numlist: The number of the elements in the array matchedlist.
+ *
+ * Find the max number of the matched entries among the array matchedlist.
+ *
+ * Return: None
+ */
+static void wlan_hdd_mdns_find_max(struct hdd_mdns_resp_matched *matchedlist,
+ uint8_t numlist)
+{
+ int j;
+ struct hdd_mdns_resp_matched tmp;
+
+ /* At least two values are used for sorting */
+ if ((numlist < 2) || (matchedlist == NULL)) {
+ hddLog(LOGE, FL("At least two values are used for sorting!"));
+ return;
+ }
+
+ for (j = 0; j < numlist-1; j++) {
+ if (matchedlist[j].num_matched >
+ matchedlist[j+1].num_matched) {
+ vos_mem_copy(&tmp, &matchedlist[j],
+ sizeof(struct hdd_mdns_resp_matched));
+ vos_mem_copy(&matchedlist[j], &matchedlist[j+1],
+ sizeof(struct hdd_mdns_resp_matched));
+ vos_mem_copy(&matchedlist[j+1], &tmp,
+ sizeof(struct hdd_mdns_resp_matched));
+ }
+ }
+}
+
+/**
+ * wlan_hdd_mdns_pack_response_type_a() - Pack Type A response
+ * @ini_config: Pointer to the struct hdd_config_t
+ * @resp_info: Pointer to the struct tSirMDNSResponseInfo
+ * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
+ *
+ * Type A response include QName, response type, class, TTL and Ipv4.
+ *
+ * Return: Return boolean. TRUE for success, FALSE for fail.
+ */
+static bool
+wlan_hdd_mdns_pack_response_type_a(hdd_config_t *ini_config,
+ sir_mdns_resp_info resp_info,
+ struct hdd_mdns_resp_info *resptype_a)
+{
+ uint16_t value;
+ uint32_t len;
+
+ ENTER();
+ if ((ini_config == NULL) || (resp_info == NULL) ||
+ (resptype_a == NULL)) {
+ hddLog(LOGE, FL("ini_config or response info is NULL!"));
+ return FALSE;
+ }
+
+ /* No Type A response */
+ if (strlen((char *)ini_config->mdns_resp_type_a) <= 0)
+ return TRUE;
+
+ /* Wrong response is assigned, just ignore this response */
+ if (!wlan_hdd_mdns_init_response(resptype_a,
+ ini_config->mdns_resp_type_a, '.'))
+ return TRUE;
+
+ /* Process response domain name */
+ if (!wlan_hdd_mdns_process_response_dname(resptype_a, resp_info)) {
+ hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
+ MDNS_TYPE_A);
+ return FALSE;
+ }
+
+ /* Process response Type, Class, TTL */
+ if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_A, resp_info)) {
+ hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
+ MDNS_TYPE_A);
+ return FALSE;
+ }
+
+ /* Process response RDLength, RData */
+ len = sizeof(uint16_t) + sizeof(uint32_t);
+ len += resp_info->resp_len;
+ if (len >= MAX_MDNS_RESP_LEN) {
+ hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
+ return FALSE;
+ }
+ value = sizeof(uint32_t);
+ wlan_hdd_mdns_format_response_u16(value, resp_info);
+ wlan_hdd_mdns_format_response_u32(ini_config->mdns_resp_type_a_ipv4,
+ resp_info);
+
+ EXIT();
+ return TRUE;
+}
+
+/**
+ * wlan_hdd_mdns_pack_response_type_txt() - Pack Type Txt response
+ * @ini_config: Pointer to the struct hdd_config_t
+ * @resp_info: Pointer to the struct tSirMDNSResponseInfo
+ * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type txt
+ * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
+ *
+ * Type Txt response include QName, response type, class, TTL and text content.
+ * Also, it will find the matched QName from resptype_A and compress the data.
+ *
+ * Return: Return boolean. TRUE for success, FALSE for fail.
+ */
+static bool
+wlan_hdd_mdns_pack_response_type_txt(hdd_config_t *ini_config,
+ sir_mdns_resp_info resp_info,
+ struct hdd_mdns_resp_info *resptype_txt,
+ struct hdd_mdns_resp_info *resptype_a)
+{
+ uint8_t num_matched;
+ uint8_t num;
+ uint16_t idx;
+ uint16_t value = 0;
+ uint32_t len;
+ uint32_t total_len;
+ bool status;
+ struct hdd_mdns_resp_info resptype_content;
+
+ ENTER();
+
+ if ((ini_config == NULL) || (resp_info == NULL) ||
+ (resptype_txt == NULL)) {
+ hddLog(LOGE, FL("ini_config or response info is NULL!"));
+ return FALSE;
+ }
+
+ /* No Type Txt response */
+ if (strlen((char *)ini_config->mdns_resp_type_txt) <= 0)
+ return TRUE;
+
+ /* Wrong response is assigned, just ignore this response */
+ if (!wlan_hdd_mdns_init_response(resptype_txt,
+ ini_config->mdns_resp_type_txt, '.'))
+ return TRUE;
+
+ /*
+ * For data compression
+ * Check if any strings are matched with Type A response
+ */
+ if (resptype_a && (resptype_a->num_entries > 0)) {
+ num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_txt,
+ resptype_a);
+ if (num_matched > 0) {
+ if (!wlan_hdd_mdns_compress_data(resp_info,
+ resptype_txt, resptype_a, num_matched)) {
+ hddLog(LOGE, FL("Fail to compress mDNS "
+ "response (%d)!"), MDNS_TYPE_TXT);
+ return FALSE;
+ }
+ } else {
+ /*
+ * num_matched is zero. Error!
+ * At least ".local" is needed.
+ */
+ hddLog(LOGE, FL("No matched string! Fail to pack mDNS "
+ "response (%d)!"), MDNS_TYPE_TXT);
+ return FALSE;
+ }
+ } else {
+ /* no TypeA response, so show the whole data */
+ if (!wlan_hdd_mdns_process_response_dname(resptype_txt,
+ resp_info)) {
+ hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
+ MDNS_TYPE_TXT);
+ return FALSE;
+ }
+ }
+
+ /* Process response Type, Class, TTL */
+ if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_TXT, resp_info)) {
+ hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
+ MDNS_TYPE_TXT);
+ return FALSE;
+ }
+
+ /*
+ * Process response RDLength, RData.
+ * TypeTxt RData include len.
+ */
+ status = wlan_hdd_mdns_init_response(&resptype_content,
+ ini_config->mdns_resp_type_txt_content,
+ '/');
+ if (status == FALSE) {
+ hddLog(LOGE, FL("wlan_hdd_mdns_init_response FAIL"));
+ return FALSE;
+ }
+
+ for (num = 0; num < resptype_content.num_entries; num++) {
+ idx = num * MAX_LEN_DOMAINNAME_FIELD;
+ value += strlen((char *)&resptype_content.data[idx]);
+ }
+
+ /* content len is uint16_t */
+ total_len = sizeof(uint16_t);
+ total_len += resp_info->resp_len + value +
+ resptype_content.num_entries;
+
+ if (total_len >= MAX_MDNS_RESP_LEN) {
+ hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
+ return FALSE;
+ }
+ wlan_hdd_mdns_format_response_u16(value + resptype_content.num_entries,
+ resp_info);
+
+ for (num = 0; num < resptype_content.num_entries; num++) {
+ idx = num * MAX_LEN_DOMAINNAME_FIELD;
+ len = strlen((char *)&resptype_content.data[idx]);
+ resp_info->resp_data[resp_info->resp_len] = len;
+ resp_info->resp_len++;
+
+ vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
+ &resptype_content.data[idx], len);
+
+ resp_info->resp_len += len;
+ hddLog(LOG1, FL("index = %d, len = %d, str = %s"),
+ num, len, &resptype_content.data[idx]);
+ }
+
+ EXIT();
+ return TRUE;
+}
+
+/**
+ * wlan_hdd_mdns_pack_response_type_ptr_dname() - Pack Type PTR domain name
+ * @ini_config: Pointer to the struct hdd_config_t
+ * @resp_info: Pointer to the struct tSirMDNSResponseInfo
+ * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
+ * domain name
+ * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
+ * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
+ * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
+ *
+ * The Type Ptr response include Type PTR domain name in its data field.
+ * Also, it will find the matched QName from the existing resptype_ptr,
+ * resptype_txt, resptype_a and then compress the data.
+ *
+ * Return: Return boolean. TRUE for success, FALSE for fail.
+ */
+static bool
+wlan_hdd_mdns_pack_response_type_ptr_dname(hdd_config_t *ini_config,
+ sir_mdns_resp_info resp_info,
+ struct hdd_mdns_resp_info *resptype_ptr_dn,
+ struct hdd_mdns_resp_info *resptype_ptr,
+ struct hdd_mdns_resp_info *resptype_txt,
+ struct hdd_mdns_resp_info *resptype_a)
+{
+ uint8_t num_matched, numlist, size;
+ struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
+ struct hdd_mdns_resp_info *resp;
+
+ if ((ini_config == NULL) || (resp_info == NULL) ||
+ (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
+ hddLog(LOGE, FL("ini_config or response info is NULL!"));
+ return FALSE;
+ }
+
+ /* No Type Ptr domain name response */
+ if (strlen((char *)ini_config->mdns_resp_type_ptr_dname) <= 0)
+ return TRUE;
+
+ /* Wrong response is assigned, just ignore this response */
+ if (!wlan_hdd_mdns_init_response(resptype_ptr_dn,
+ ini_config->mdns_resp_type_ptr_dname, '.'))
+ return TRUE;
+
+ /*
+ * For data compression
+ * Check if any strings are matched with previous
+ * response.
+ */
+ numlist = 0;
+ size = (MAX_MDNS_RESP_TYPE-1);
+ size *= sizeof(struct hdd_mdns_resp_matched);
+ vos_mem_zero(matchedlist, size);
+ num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr_dn,
+ resptype_ptr);
+ if (num_matched > 0) {
+ matchedlist[numlist].num_matched = num_matched;
+ matchedlist[numlist].type = MDNS_TYPE_PTR;
+ numlist++;
+ }
+ if (resptype_txt && (resptype_txt->num_entries > 0)) {
+ num_matched = wlan_hdd_mdns_find_entries_from_end(
+ resptype_ptr_dn, resptype_txt);
+ if (num_matched > 0) {
+ matchedlist[numlist].num_matched = num_matched;
+ matchedlist[numlist].type = MDNS_TYPE_TXT;
+ numlist++;
+ }
+ }
+ if (resptype_a && (resptype_a->num_entries > 0)) {
+ num_matched = wlan_hdd_mdns_find_entries_from_end(
+ resptype_ptr_dn,resptype_a);
+ if (num_matched > 0) {
+ matchedlist[numlist].num_matched = num_matched;
+ matchedlist[numlist].type = MDNS_TYPE_A;
+ numlist++;
+ }
+ }
+ if (numlist > 0) {
+ if (numlist > 1)
+ wlan_hdd_mdns_find_max(matchedlist, numlist);
+ resp = NULL;
+ switch (matchedlist[numlist-1].type) {
+ case MDNS_TYPE_A:
+ resp = resptype_a;
+ break;
+ case MDNS_TYPE_TXT:
+ resp = resptype_txt;
+ break;
+ case MDNS_TYPE_PTR:
+ resp = resptype_ptr;
+ break;
+ default:
+ hddLog(LOGE, FL("Fail to compress mDNS response "
+ "(%d)!"), MDNS_TYPE_PTR_DNAME);
+ return FALSE;
+ }
+ num_matched = matchedlist[numlist-1].num_matched;
+ if (!wlan_hdd_mdns_compress_data(resp_info, resptype_ptr_dn,
+ resp, num_matched)) {
+ hddLog(LOGE, FL("Fail to compress mDNS response "
+ "(%d)!"), MDNS_TYPE_PTR_DNAME);
+ return FALSE;
+ }
+ } else {
+ /* num = 0 -> no matched string */
+ if (!wlan_hdd_mdns_process_response_dname(resptype_ptr_dn,
+ resp_info)) {
+ hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
+ MDNS_TYPE_PTR_DNAME);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/**
+ * wlan_hdd_mdns_pack_response_type_ptr() - Pack Type PTR response
+ * @ini_config: Pointer to the struct hdd_config_t
+ * @resp_info: Pointer to the struct tSirMDNSResponseInfo
+ * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
+ * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
+ * domain name
+ * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
+ * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
+ *
+ * The Type Ptr response include QName, response type, class, TTL and
+ * Type PTR domain name. Also, it will find the matched QName from the
+ * existing resptype_txt, resptype_a and then compress the data.
+ *
+ * Return: Return boolean. TRUE for success, FALSE for fail.
+ */
+static bool
+wlan_hdd_mdns_pack_response_type_ptr(hdd_config_t *ini_config,
+ sir_mdns_resp_info resp_info,
+ struct hdd_mdns_resp_info *resptype_ptr,
+ struct hdd_mdns_resp_info *resptype_ptr_dn,
+ struct hdd_mdns_resp_info *resptype_txt,
+ struct hdd_mdns_resp_info *resptype_a)
+{
+ uint8_t num_matched, num_matched1;
+ uint16_t value;
+ uint8_t val_u8;
+ uint32_t offset_data_len, len;
+
+ ENTER();
+ if ((ini_config == NULL) || (resp_info == NULL) ||
+ (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
+ hddLog(LOGE, FL("ini_config or response info is NULL!"));
+ return FALSE;
+ }
+
+ /* No Type Ptr response */
+ if (strlen((char *)ini_config->mdns_resp_type_ptr) <= 0)
+ return TRUE;
+
+ /* Wrong response is assigned, just ignore this response */
+ if (!wlan_hdd_mdns_init_response(resptype_ptr,
+ ini_config->mdns_resp_type_ptr, '.'))
+ return TRUE;
+
+ /*
+ * For data compression
+ * Check if any strings are matched with Type A response
+ */
+ num_matched = 0;
+ num_matched1 = 0;
+ if (resptype_a && (resptype_a->num_entries > 0)) {
+ num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr,
+ resptype_a);
+ }
+ if (resptype_txt && (resptype_txt->num_entries > 0)) {
+ num_matched1 = wlan_hdd_mdns_find_entries_from_end(
+ resptype_ptr, resptype_txt);
+ }
+ if ((num_matched != num_matched1) ||
+ ((num_matched > 0) && (num_matched1 > 0))) {
+ if (num_matched >= num_matched1) {
+ if (!wlan_hdd_mdns_compress_data(resp_info,
+ resptype_ptr, resptype_a, num_matched)) {
+ hddLog(LOGE, FL("Fail to compress mDNS "
+ "response (%d)!"), MDNS_TYPE_PTR);
+ return FALSE;
+ }
+ } else {
+ /* num_matched is less than num_matched1 */
+ if (!wlan_hdd_mdns_compress_data(resp_info,
+ resptype_ptr, resptype_txt, num_matched1)) {
+ hddLog(LOGE, FL("Fail to compress mDNS "
+ "response (%d)!"), MDNS_TYPE_PTR);
+ return FALSE;
+ }
+ }
+ } else {
+ /*
+ * Both num_matched and num_matched1 are zero.
+ * no TypeA & TypeTxt
+ */
+ if (!wlan_hdd_mdns_process_response_dname(resptype_ptr,
+ resp_info)) {
+ hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
+ MDNS_TYPE_PTR);
+ return FALSE;
+ }
+ }
+
+ /* Process response Type, Class, TTL */
+ if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_PTR, resp_info)) {
+ hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
+ MDNS_TYPE_PTR);
+ return FALSE;
+ }
+
+ /*
+ * Process response RDLength, RData (Ptr domain name)
+ * Save the offset of RData length
+ */
+ offset_data_len = resp_info->resp_len;
+ resp_info->resp_len += sizeof(uint16_t);
+
+ if (!wlan_hdd_mdns_pack_response_type_ptr_dname(ini_config, resp_info,
+ resptype_ptr_dn, resptype_ptr,
+ resptype_txt, resptype_a)) {
+ return FALSE;
+ }
+ /* Set the RData length */
+ len = offset_data_len + sizeof(uint16_t);
+ if ((resptype_ptr_dn->num_entries > 0) &&
+ (resp_info->resp_len > len)) {
+ value = resp_info->resp_len - len;
+ val_u8 = (value & 0xff00) >> 8;
+ resp_info->resp_data[offset_data_len] = val_u8;
+ val_u8 = value & 0xff;
+ resp_info->resp_data[offset_data_len+1] = val_u8;
+ } else {
+ hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
+ MDNS_TYPE_PTR);
+ return FALSE;
+ }
+
+ EXIT();
+ return TRUE;
+}
+
+/**
+ * wlan_hdd_mdns_pack_response_type_srv_target()- Pack Type Service Target
+ * @ini_config: Pointer to the struct hdd_config_t
+ * @resp_info: Pointer to the struct tSirMDNSResponseInfo
+ * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
+ * target
+ * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
+ * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
+ * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
+ * domain name
+ * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
+ * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
+ *
+ * The Type service target is one of the data field in the Type SRV response.
+ * Also, it will find the matched QName from the existing resptype_srv,
+ * resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and then compress
+ * the data.
+ *
+ * Return: Return boolean. TRUE for success, FALSE for fail.
+ */
+static bool
+wlan_hdd_mdns_pack_response_type_srv_target(hdd_config_t *ini_config,
+ sir_mdns_resp_info resp_info,
+ struct hdd_mdns_resp_info *resptype_srv_tgt,
+ struct hdd_mdns_resp_info *resptype_srv,
+ struct hdd_mdns_resp_info *resptype_ptr,
+ struct hdd_mdns_resp_info *resptype_ptr_dn,
+ struct hdd_mdns_resp_info *resptype_txt,
+ struct hdd_mdns_resp_info *resptype_a)
+{
+ uint8_t num_matched, num, size;
+ struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
+ struct hdd_mdns_resp_info *resp;
+
+ if ((ini_config == NULL) || (resp_info == NULL) ||
+ (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
+ hddLog(LOGE, FL("ini_config or response info is NULL!"));
+ return FALSE;
+ }
+
+ /* No Type Srv Target response */
+ if (strlen((char *)ini_config->mdns_resp_type_srv_target) <= 0)
+ return TRUE;
+
+ /* Wrong response is assigned, just ignore this response */
+ if (!wlan_hdd_mdns_init_response(resptype_srv_tgt,
+ ini_config->mdns_resp_type_srv_target, '.'))
+ return TRUE;
+
+ /*
+ * For data compression
+ * Check if any strings are matched with previous response.
+ */
+ num = 0;
+ size = (MAX_MDNS_RESP_TYPE-1);
+ size *= sizeof(struct hdd_mdns_resp_matched);
+ vos_mem_zero(matchedlist, size);
+ num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv_tgt,
+ resptype_srv);
+ if (num_matched > 0) {
+ matchedlist[num].num_matched = num_matched;
+ matchedlist[num].type = MDNS_TYPE_SRV;
+ num++;
+ }
+ if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
+ if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
+ num_matched = wlan_hdd_mdns_find_entries_from_end(
+ resptype_srv_tgt, resptype_ptr_dn);
+ if (num_matched > 0) {
+ matchedlist[num].num_matched = num_matched;
+ matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
+ num++;
+ }
+ }
+ num_matched = wlan_hdd_mdns_find_entries_from_end(
+ resptype_srv_tgt, resptype_ptr);
+ if (num_matched > 0) {
+ matchedlist[num].num_matched = num_matched;
+ matchedlist[num].type = MDNS_TYPE_PTR;
+ num++;
+ }
+ }
+ if (resptype_txt && (resptype_txt->num_entries > 0)) {
+ num_matched = wlan_hdd_mdns_find_entries_from_end(
+ resptype_srv_tgt, resptype_txt);
+ if (num_matched > 0) {
+ matchedlist[num].num_matched = num_matched;
+ matchedlist[num].type = MDNS_TYPE_TXT;
+ num++;
+ }
+ }
+ if (resptype_a && (resptype_a->num_entries > 0)) {
+ num_matched = wlan_hdd_mdns_find_entries_from_end(
+ resptype_srv_tgt, resptype_a);
+ if (num_matched > 0) {
+ matchedlist[num].num_matched = num_matched;
+ matchedlist[num].type = MDNS_TYPE_A;
+ num++;
+ }
+ }
+ if (num > 0) {
+ if (num > 1)
+ wlan_hdd_mdns_find_max(matchedlist, num);
+ resp = NULL;
+ switch (matchedlist[num-1].type) {
+ case MDNS_TYPE_A:
+ resp = resptype_a;
+ break;
+ case MDNS_TYPE_TXT:
+ resp = resptype_txt;
+ break;
+ case MDNS_TYPE_PTR:
+ resp = resptype_ptr;
+ break;
+ case MDNS_TYPE_PTR_DNAME:
+ resp = resptype_ptr_dn;
+ break;
+ case MDNS_TYPE_SRV:
+ resp = resptype_srv;
+ break;
+ default:
+ hddLog(LOGE, FL("Fail to compress mDNS response "
+ "(%d)!"), MDNS_TYPE_SRV_TARGET);
+ return FALSE;
+ }
+ num_matched = matchedlist[num-1].num_matched;
+ if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv_tgt,
+ resp, num_matched)) {
+ hddLog(LOGE, FL("Fail to compress mDNS response "
+ "(%d)!"), MDNS_TYPE_SRV_TARGET);
+ return FALSE;
+ }
+ } else {
+ /* num = 0 -> no matched string */
+ if (!wlan_hdd_mdns_process_response_dname(resptype_srv_tgt,
+ resp_info)) {
+ hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
+ MDNS_TYPE_SRV_TARGET);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/**
+ * wlan_hdd_mdns_pack_response_type_srv()- Pack Type Service response
+ * @ini_config: Pointer to the struct hdd_config_t
+ * @resp_info: Pointer to the struct tSirMDNSResponseInfo
+ * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
+ * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
+ * target
+ * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
+ * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
+ * domain name
+ * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
+ * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
+ *
+ * The Type SRV (Service) response include QName, response type, class, TTL
+ * and four kinds of data fields. Also, it will find the matched QName from
+ * the existing resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and
+ * then compress the data.
+ *
+ * Return: Return boolean. TRUE for success, FALSE for fail.
+ */
+static bool
+wlan_hdd_mdns_pack_response_type_srv(hdd_config_t *ini_config,
+ sir_mdns_resp_info resp_info,
+ struct hdd_mdns_resp_info *resptype_srv,
+ struct hdd_mdns_resp_info *resptype_srv_tgt,
+ struct hdd_mdns_resp_info *resptype_ptr,
+ struct hdd_mdns_resp_info *resptype_ptr_dn,
+ struct hdd_mdns_resp_info *resptype_txt,
+ struct hdd_mdns_resp_info *resptype_a)
+{
+ uint8_t num_matched, num, size;
+ uint16_t value;
+ uint8_t val_u8;
+ uint32_t offset_data_len, len;
+ struct hdd_mdns_resp_info *resp;
+ struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
+
+ ENTER();
+
+ if ((ini_config == NULL) || (resp_info == NULL) ||
+ (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
+ hddLog(LOGE, FL("ini_config or response info is NULL!"));
+ return FALSE;
+ }
+
+ /* No Type Srv response */
+ if (strlen((char *)ini_config->mdns_resp_type_srv) <= 0)
+ return TRUE;
+
+ /* Wrong response is assigned, just ignore this response */
+ if (!wlan_hdd_mdns_init_response(resptype_srv,
+ ini_config->mdns_resp_type_srv, '.'))
+ return TRUE;
+
+ /*
+ * For data compression
+ * Check if any strings are matched with Type A response
+ */
+ num = 0;
+ size = (MAX_MDNS_RESP_TYPE-1);
+ size *= sizeof(struct hdd_mdns_resp_matched);
+ vos_mem_zero(matchedlist, size);
+ if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
+ if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
+ num_matched = wlan_hdd_mdns_find_entries_from_end(
+ resptype_srv,
+ resptype_ptr_dn);
+ if (num_matched > 0) {
+ matchedlist[num].num_matched = num_matched;
+ matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
+ num++;
+ }
+ }
+ num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
+ resptype_ptr);
+ if (num_matched > 0) {
+ matchedlist[num].num_matched = num_matched;
+ matchedlist[num].type = MDNS_TYPE_PTR;
+ num++;
+ }
+ }
+ if (resptype_txt && (resptype_txt->num_entries > 0)) {
+ num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
+ resptype_txt);
+ if (num_matched > 0) {
+ matchedlist[num].num_matched =num_matched;
+ matchedlist[num].type = MDNS_TYPE_TXT;
+ num++;
+ }
+ }
+ if (resptype_a && (resptype_a->num_entries > 0)) {
+ num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
+ resptype_a);
+ if (num_matched > 0) {
+ matchedlist[num].num_matched = num_matched;
+ matchedlist[num].type = MDNS_TYPE_A;
+ num++;
+ }
+ }
+ if (num > 0) {
+ if (num > 1)
+ wlan_hdd_mdns_find_max(matchedlist, num);
+ resp = NULL;
+ switch (matchedlist[num-1].type) {
+ case MDNS_TYPE_A:
+ resp = resptype_a;
+ break;
+ case MDNS_TYPE_TXT:
+ resp = resptype_txt;
+ break;
+ case MDNS_TYPE_PTR:
+ resp = resptype_ptr;
+ break;
+ case MDNS_TYPE_PTR_DNAME:
+ resp = resptype_ptr_dn;
+ break;
+ default:
+ hddLog(LOGE, FL("Fail to compress mDNS response "
+ "(%d)!"), MDNS_TYPE_SRV);
+ return FALSE;
+ }
+ num_matched = matchedlist[num-1].num_matched;
+ if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv,
+ resp, num_matched)) {
+ hddLog(LOGE, FL("Fail to compress mDNS response "
+ "(%d)!"), MDNS_TYPE_SRV);
+ return FALSE;
+ }
+ } else {
+ /* num = 0 -> no matched string */
+ if (!wlan_hdd_mdns_process_response_dname(resptype_srv,
+ resp_info)) {
+ hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
+ MDNS_TYPE_SRV);
+ return FALSE;
+ }
+ }
+
+ /* Process response Type, Class, TTL */
+ if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_SRV, resp_info)) {
+ hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
+ MDNS_TYPE_SRV);
+ return FALSE;
+ }
+
+ /*
+ * Process response RDLength, RData (Srv target name)
+ * Save the offset of RData length
+ */
+ offset_data_len = resp_info->resp_len;
+ resp_info->resp_len += sizeof(uint16_t);
+
+ len = resp_info->resp_len + (3 * sizeof(uint16_t));
+ if (len >= MAX_MDNS_RESP_LEN) {
+ hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
+ return FALSE;
+ }
+
+ /* set Srv Priority */
+ value = ini_config->mdns_resp_type_srv_priority;
+ wlan_hdd_mdns_format_response_u16(value, resp_info);
+ /* set Srv Weight */
+ value = ini_config->mdns_resp_type_srv_weight;
+ wlan_hdd_mdns_format_response_u16(value, resp_info);
+ /* set Srv Port */
+ value = ini_config->mdns_resp_type_srv_port;
+ wlan_hdd_mdns_format_response_u16(value, resp_info);
+
+ if (!wlan_hdd_mdns_pack_response_type_srv_target(ini_config, resp_info,
+ resptype_srv_tgt, resptype_srv,
+ resptype_ptr, resptype_ptr_dn,
+ resptype_txt, resptype_a)) {
+ return FALSE;
+ }
+ /* Set the RData length */
+ len = offset_data_len + sizeof(uint16_t);
+ if ((resptype_srv_tgt->num_entries > 0) &&
+ (resp_info->resp_len > len)) {
+ value = resp_info->resp_len - len;
+ val_u8 = (value & 0xff00) >> 8;
+ resp_info->resp_data[offset_data_len] = val_u8;
+ val_u8 = value & 0xff;
+ resp_info->resp_data[offset_data_len+1] = val_u8;
+ } else {
+ hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
+ MDNS_TYPE_SRV);
+ return FALSE;
+ }
+
+ EXIT();
+ return TRUE;
+}
+
+/**
+ * wlan_hdd_mdns_free_mem() - Free the allocated memory
+ * @response: Pointer to the struct hdd_mdns_resp_info
+ *
+ * Return: None
+ */
+static void wlan_hdd_mdns_free_mem(struct hdd_mdns_resp_info *response)
+{
+ if (response && response->data)
+ vos_mem_free(response->data);
+ if (response && response->offset)
+ vos_mem_free(response->offset);
+}
+
+/**
+ * wlan_hdd_mdns_pack_response() - Pack mDNS response
+ * @ini_config: Pointer to the struct hdd_config_t
+ * @resp_info: Pointer to the struct tSirMDNSResponseInfo
+ *
+ * This function will pack four types of responses (Type A, Type Txt, Type Ptr
+ * and Type Service). Each response contains QName, response type, class, TTL
+ * and data fields.
+ *
+ * Return: Return boolean. TRUE for success, FALSE for fail.
+ */
+static bool wlan_hdd_mdns_pack_response(hdd_config_t *ini_config,
+ sir_mdns_resp_info resp_info)
+{
+ struct hdd_mdns_resp_info resptype_a, resptype_txt;
+ struct hdd_mdns_resp_info resptype_ptr, resptype_ptr_dn;
+ struct hdd_mdns_resp_info resptype_srv, resptype_srv_tgt;
+ uint32_t num_res_records = 0;
+ bool status = FALSE;
+
+ ENTER();
+
+ wlan_hdd_mdns_reset_response(&resptype_a);
+ wlan_hdd_mdns_reset_response(&resptype_txt);
+ wlan_hdd_mdns_reset_response(&resptype_ptr);
+ wlan_hdd_mdns_reset_response(&resptype_ptr_dn);
+ wlan_hdd_mdns_reset_response(&resptype_srv);
+ wlan_hdd_mdns_reset_response(&resptype_srv_tgt);
+
+ resp_info->resp_len = 0;
+
+ /* Process Type A response */
+ if (!wlan_hdd_mdns_pack_response_type_a(ini_config, resp_info,
+ &resptype_a))
+ goto err_resptype_a;
+
+ if ((resptype_a.num_entries > 0) &&
+ (strlen((char *)&resptype_a.data[0]) > 0))
+ num_res_records++;
+
+ /* Process Type TXT response */
+ if (!wlan_hdd_mdns_pack_response_type_txt(ini_config, resp_info,
+ &resptype_txt, &resptype_a))
+ goto err_resptype_txt;
+
+ if ((resptype_txt.num_entries > 0) &&
+ (strlen((char *)&resptype_txt.data[0]) > 0))
+ num_res_records++;
+
+ /* Process Type PTR response */
+ if (!wlan_hdd_mdns_pack_response_type_ptr(ini_config, resp_info,
+ &resptype_ptr, &resptype_ptr_dn,
+ &resptype_txt, &resptype_a))
+ goto err_resptype_ptr;
+
+ if ((resptype_ptr.num_entries > 0) &&
+ (strlen((char *)&resptype_ptr.data[0]) > 0))
+ num_res_records++;
+
+ /* Process Type SRV response */
+ if (!wlan_hdd_mdns_pack_response_type_srv(ini_config, resp_info,
+ &resptype_srv, &resptype_srv_tgt,
+ &resptype_ptr, &resptype_ptr_dn,
+ &resptype_txt, &resptype_a))
+ goto err_resptype_srv;
+
+ if ((resptype_srv.num_entries > 0) &&
+ (strlen((char *)&resptype_srv.data[0]) > 0))
+ num_res_records++;
+
+ resp_info->resourceRecord_count = num_res_records;
+ hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
+ "%s: Pack mDNS response data successfully!", __func__);
+ status = TRUE;
+
+err_resptype_srv:
+ wlan_hdd_mdns_free_mem(&resptype_srv);
+ wlan_hdd_mdns_free_mem(&resptype_srv_tgt);
+
+err_resptype_ptr:
+ wlan_hdd_mdns_free_mem(&resptype_ptr);
+ wlan_hdd_mdns_free_mem(&resptype_ptr_dn);
+
+err_resptype_txt:
+ wlan_hdd_mdns_free_mem(&resptype_txt);
+
+err_resptype_a:
+ wlan_hdd_mdns_free_mem(&resptype_a);
+
+ EXIT();
+ return status;
+}
+
+/**
+ * wlan_hdd_set_mdns_offload() - Enable mDNS offload
+ * @hostapd_adapter: Pointer to the struct hdd_adapter_t
+ *
+ * This function will set FQDN/unique FQDN (full qualified domain name)
+ * and the mDNS response. Then send them to SME.
+ *
+ * Return: Return boolean. TRUE for success, FALSE for fail.
+ */
+bool wlan_hdd_set_mdns_offload(hdd_adapter_t *hostapd_adapter)
+{
+ hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
+ sir_mdns_offload_info mdns_offload_info;
+ sir_mdns_fqdn_info mdns_fqdn_info;
+ sir_mdns_resp_info mdns_resp_info;
+ uint32_t fqdn_len, ufqdn_len;
+
+ ENTER();
+
+ /* 1. Prepare the MDNS fqdn request to send to SME */
+ fqdn_len = strlen(hdd_ctx->cfg_ini->mdns_fqdn);
+ ufqdn_len = strlen(hdd_ctx->cfg_ini->mdns_uniquefqdn);
+ if ((fqdn_len == 0) && (ufqdn_len == 0)) {
+ hddLog(LOGE, FL("No mDNS FQDN or UFQDN is assigned fqdn_len %d,"
+ "ufqdn_len %d!"), fqdn_len, ufqdn_len);
+ return FALSE;
+ }
+
+ mdns_fqdn_info = vos_mem_malloc(sizeof(*mdns_fqdn_info));
+ if (NULL == mdns_fqdn_info) {
+ hddLog(LOGE, FL("could not allocate tSirMDNSFqdnInfo!"));
+ return FALSE;
+ }
+ /* MDNS fqdn request */
+ if (fqdn_len > 0) {
+ vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
+ mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
+ mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_GENERAL;
+ mdns_fqdn_info->fqdn_len = fqdn_len;
+ mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
+ mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
+ vos_mem_copy(mdns_fqdn_info->fqdn_data,
+ hdd_ctx->cfg_ini->mdns_fqdn,
+ mdns_fqdn_info->fqdn_len);
+
+ if (eHAL_STATUS_SUCCESS !=
+ sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
+ hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
+ vos_mem_free(mdns_fqdn_info);
+ return FALSE;
+ }
+ }
+ /* MDNS unique fqdn request */
+ if (ufqdn_len > 0) {
+ vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
+ mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
+ mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_UNIQUE;
+ mdns_fqdn_info->fqdn_len = ufqdn_len;
+ mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
+ mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
+ vos_mem_copy(mdns_fqdn_info->fqdn_data,
+ hdd_ctx->cfg_ini->mdns_uniquefqdn,
+ mdns_fqdn_info->fqdn_len);
+ if (eHAL_STATUS_SUCCESS !=
+ sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
+ hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
+ vos_mem_free(mdns_fqdn_info);
+ return FALSE;
+ }
+ }
+ vos_mem_free(mdns_fqdn_info);
+
+ /* 2. Prepare the MDNS response request to send to SME */
+ mdns_resp_info = vos_mem_malloc(sizeof(*mdns_resp_info));
+ if (NULL == mdns_resp_info) {
+ hddLog(LOGE, FL("could not allocate tSirMDNSResponseInfo!"));
+ return FALSE;
+ }
+
+ vos_mem_zero(mdns_resp_info, sizeof(*mdns_resp_info));
+ mdns_resp_info->bss_idx = hostapd_adapter->sessionId;
+ mdns_resp_info->mdns_resp_callback = hdd_mdns_resp_offload_done;
+ mdns_resp_info->mdns_resp_cb_context = hostapd_adapter;
+ if (!wlan_hdd_mdns_pack_response(hdd_ctx->cfg_ini, mdns_resp_info)) {
+ hddLog(LOGE, FL("wlan_hdd_pack_mdns_response fail!"));
+ vos_mem_free(mdns_resp_info);
+ return FALSE;
+ }
+ if (eHAL_STATUS_SUCCESS !=
+ sme_set_mdns_resp(hdd_ctx->hHal, mdns_resp_info)) {
+ hddLog(LOGE, FL("sme_set_mdns_resp fail!"));
+ vos_mem_free(mdns_resp_info);
+ return FALSE;
+ }
+ vos_mem_free(mdns_resp_info);
+
+ /* 3. Prepare the MDNS Enable request to send to SME */
+ mdns_offload_info = vos_mem_malloc(sizeof(*mdns_offload_info));
+ if (NULL == mdns_offload_info) {
+ hddLog(LOGE, FL("could not allocate tSirMDNSOffloadInfo!"));
+ return FALSE;
+ }
+
+ vos_mem_zero(mdns_offload_info, sizeof(*mdns_offload_info));
+
+ mdns_offload_info->bss_idx = hostapd_adapter->sessionId;
+ mdns_offload_info->enable = hdd_ctx->cfg_ini->enable_mdns_offload;
+ mdns_offload_info->mdns_enable_callback = hdd_mdns_enable_offload_done;
+ mdns_offload_info->mdns_enable_cb_context = hostapd_adapter;
+ if (eHAL_STATUS_SUCCESS !=
+ sme_set_mdns_offload(hdd_ctx->hHal, mdns_offload_info)) {
+ hddLog(LOGE, FL("sme_set_mdns_offload fail!"));
+ vos_mem_free(mdns_offload_info);
+ return FALSE;
+ }
+
+ vos_mem_free(mdns_offload_info);
+ hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
+ "%s: enable mDNS offload successfully!", __func__);
+ return TRUE;
+}
+
+
+#endif /* MDNS_OFFLOAD */
/**
* wlan_hdd_start_sap() - This function starts bss of SAP.
@@ -14911,6 +16707,314 @@ end:
return;
}
+#ifdef WLAN_FEATURE_TSF
+
+/**
+ * hdd_tsf_cb() - handle tsf request callback
+ *
+ * @pcb_cxt: pointer to the hdd_contex
+ * @ptsf: pointer to struct stsf
+ *
+ * Based on the request sent .
+ *
+ * Return: Describe the execute result of this routine
+ */
+static int hdd_tsf_cb(void *pcb_ctx, struct stsf *ptsf)
+{
+ hdd_context_t *hddctx;
+ int status;
+ hdd_adapter_t* adapter = (hdd_adapter_t*)pcb_ctx;
+
+ if (pcb_ctx == NULL || ptsf == NULL) {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ FL("HDD context is not valid"));
+ return -EINVAL;
+ }
+
+ hddctx = (hdd_context_t *)pcb_ctx;
+ status = wlan_hdd_validate_context(hddctx);
+ if (0 != status)
+ return -EINVAL;
+
+ if (NULL == adapter) {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ FL("failed to find adapter"));
+ return -EINVAL;
+ }
+
+ hddLog(VOS_TRACE_LEVEL_INFO,
+ FL("tsf cb handle event, device_mode is %d"),
+ adapter->device_mode);
+
+ /* copy the return value to hdd_tsf_ctx in adapter*/
+ if (ptsf->tsf_req_status) {
+
+ vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
+ adapter->tsf_cap_ctx.tsf_get_state = TSF_NOT_RETURNED_BY_FW;
+ adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
+ vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
+ vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
+
+ hddLog(VOS_TRACE_LEVEL_ERROR, FL("tsf req failure :%d"),
+ ptsf->tsf_req_status);
+ return ptsf->tsf_req_status;
+ }
+ /* If this is a get request.Store the tsf values in adapter. */
+ if (!ptsf->set_tsf_req) {
+ vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
+ adapter->tsf_cap_ctx.tsf_low = ptsf->tsf_low;
+ adapter->tsf_cap_ctx.tsf_high = ptsf->tsf_high;
+ adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
+ adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
+ vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
+
+ hddLog(VOS_TRACE_LEVEL_INFO,
+ FL("hdd_get_tsf_cb sta=%u, tsf_low=%u, tsf_high=%u"),
+ adapter->sessionId, ptsf->tsf_low, ptsf->tsf_high);
+ }
+ else {
+ vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
+ adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
+ adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
+ vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
+ }
+ vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
+ vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
+ vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
+
+ /* free allocated mem */
+ vos_mem_free(ptsf);
+
+ return 0;
+}
+
+/**
+ * hdd_capture_tsf() - capture tsf
+ *
+ * @adapter: pointer to adapter
+ * @buf: pointer to upper layer buf
+ * @len : the length of buf
+ *
+ * This function returns tsf value to uplayer.
+ *
+ * Return: Describe the execute result of this routine
+ */
+int hdd_capture_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
+{
+ int ret = 0;
+ hdd_station_ctx_t *hdd_sta_ctx;
+ hdd_context_t *hdd_ctx;
+ tSirCapTsfParams cap_tsf_params;
+ VOS_STATUS status;
+
+ if (adapter == NULL || buf == NULL) {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ FL("invalid pointer"));
+ return -EINVAL;
+ }
+ if (len != 1)
+ return -EINVAL;
+
+ hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+ if (wlan_hdd_validate_context(hdd_ctx)) {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ FL("invalid hdd ctx"));
+ return -EINVAL;
+ }
+ if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
+ adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
+ hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+ if (hdd_sta_ctx->conn_info.connState !=
+ eConnectionState_Associated) {
+
+ hddLog(VOS_TRACE_LEVEL_INFO,
+ FL("failed to cap tsf, not connect with ap"));
+ buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
+ return ret;
+ }
+ }
+ if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
+ adapter->device_mode == WLAN_HDD_P2P_GO) &&
+ !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
+ hddLog(VOS_TRACE_LEVEL_INFO,
+ FL("Soft AP / P2p GO not beaconing"));
+ buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
+ return ret;
+ }
+ if (adapter->tsf_cap_ctx.tsf_capture_state == TSF_CAP_STATE) {
+ hddLog(VOS_TRACE_LEVEL_INFO,
+ FL("current in capture state, pls reset"));
+ buf[0] = TSF_CURRENT_IN_CAP_STATE;
+ } else {
+ hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
+ buf[0] = TSF_RETURN;
+ cap_tsf_params.session_id = adapter->sessionId;
+ cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
+ cap_tsf_params.tsf_rsp_cb_ctx = adapter;
+
+ vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
+ adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
+ adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
+ vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
+
+ ret = sme_capture_tsf_req(hdd_ctx->hHal, cap_tsf_params);
+
+ if (ret != VOS_STATUS_SUCCESS) {
+ hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
+ buf[0] = TSF_CAPTURE_FAIL;
+ vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
+ adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
+ vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
+ return -EINVAL;
+ }
+ /* wait till we get a response from fw */
+ status = vos_wait_single_event(&adapter->tsf_cap_ctx.
+ tsf_capture_done_event,
+ HDD_TSF_CAP_REQ_TIMEOUT);
+
+ if (!VOS_IS_STATUS_SUCCESS(status)) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ ("capture tsf vos wait for single_event failed!! %d"),
+ adapter->tsf_cap_ctx.tsf_get_state);
+
+ vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
+ adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
+ vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
+
+ return -EINVAL;
+ }
+ }
+ buf[0] = TSF_RETURN;
+ hddLog(VOS_TRACE_LEVEL_INFO,
+ FL("ioctl return cap tsf cmd, ret = %d"), ret);
+ return ret;
+}
+
+/**
+ * hdd_indicate_tsf() - return tsf to uplayer
+ *
+ * @adapter: pointer to adapter
+ * @buf: pointer to uplayer buf
+ * @len : the length of buf
+ *
+ * This function returns tsf value to uplayer.
+ *
+ * Return: Describe the execute result of this routine
+ */
+int hdd_indicate_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
+{
+ int ret = 0;
+ hdd_station_ctx_t *hdd_sta_ctx;
+ hdd_context_t *hdd_ctx;
+ tSirCapTsfParams cap_tsf_params;
+ VOS_STATUS status;
+
+ if (adapter == NULL || buf == NULL) {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ FL("invalid pointer"));
+ return -EINVAL;
+ }
+ if (len != 3)
+ return -EINVAL;
+
+ buf [1] = 0;
+ buf [2] = 0;
+ hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+ if (wlan_hdd_validate_context(hdd_ctx)) {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ FL("invalid hdd ctx"));
+ return -EINVAL;
+ }
+ if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
+ adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
+ hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+ if (hdd_sta_ctx->conn_info.connState !=
+ eConnectionState_Associated) {
+
+ hddLog(VOS_TRACE_LEVEL_INFO,
+ FL("failed to cap tsf, not connect with ap"));
+ buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
+ return ret;
+ }
+ }
+ if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
+ adapter->device_mode == WLAN_HDD_P2P_GO) &&
+ !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
+ hddLog(VOS_TRACE_LEVEL_INFO,
+ FL("Soft AP / P2p GO not beaconing"));
+ buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
+ return ret;
+ }
+
+ if (adapter->tsf_cap_ctx.tsf_capture_state != TSF_CAP_STATE ||
+ adapter->tsf_cap_ctx.tsf_get_state != TSF_CURRENT_IN_CAP_STATE ) {
+ hddLog(VOS_TRACE_LEVEL_INFO,
+ FL("Not in capture state,Enter capture state first"));
+ buf[0] = TSF_GET_FAIL;
+ } else {
+ hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
+ cap_tsf_params.session_id = adapter->sessionId;
+ cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
+ cap_tsf_params.tsf_rsp_cb_ctx = adapter;
+
+ ret = sme_get_tsf_req(hdd_ctx->hHal, cap_tsf_params);
+
+ if (ret != VOS_STATUS_SUCCESS) {
+ hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
+ buf[0] = TSF_CAPTURE_FAIL;
+ vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
+ adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
+ vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
+ return -EINVAL;
+ }
+ /* wait till we get a response from fw */
+ status = vos_wait_single_event(&adapter->tsf_cap_ctx.
+ tsf_capture_done_event,
+ HDD_TSF_GET_REQ_TIMEOUT);
+
+ if (!VOS_IS_STATUS_SUCCESS(status)) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ ("capture tsf vos wait for single_event failed!! %d"),
+ status);
+
+ vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
+ adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
+ vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
+ return status;
+ }
+ buf[1] = adapter->tsf_cap_ctx.tsf_low;
+ buf[2] = adapter->tsf_cap_ctx.tsf_high;
+
+ hddLog(VOS_TRACE_LEVEL_INFO,
+ FL("get tsf cmd,status=%u, tsf_low=%u, tsf_high=%u"),
+ buf[0], buf[1], buf[2]);
+ }
+ hddLog(VOS_TRACE_LEVEL_INFO,
+ FL("ioctl return cap tsf cmd, ret = %d"), ret);
+ return ret;
+}
+
+void wlan_hdd_tsf_init(hdd_adapter_t *adapter)
+{
+
+ if (adapter == NULL) {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ FL("TSF init on a null adapter!"));
+ return;
+ }
+
+ adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
+ adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
+ vos_event_init(&adapter->tsf_cap_ctx.tsf_capture_done_event);
+ vos_spin_lock_init(&adapter->tsf_cap_ctx.tsf_lock);
+ adapter->tsf_cap_ctx.tsf_high = 0;
+ adapter->tsf_cap_ctx.tsf_low = 0;
+}
+
+#endif
+
//Register the module init/exit functions
module_init(hdd_module_init);
module_exit(hdd_module_exit);
diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_oemdata.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_oemdata.c
index 9bc83726bef..df015ac40a5 100644
--- a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_oemdata.c
+++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_oemdata.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -992,5 +992,20 @@ int oem_activate_service(void *pAdapter)
return 0;
}
+/**---------------------------------------------------------------------------
+
+ \brief oem_deactivate_service() - Deactivate oem message handler
+
+ This function unregisters a handler to receive netlink message from
+ an OEM application process.
+
+ \return - none
+ --------------------------------------------------------------------------*/
+void oem_deactivate_service()
+{
+ /* unregister the msg handler for msgs addressed to WLAN_NL_MSG_OEM */
+ nl_srv_unregister(WLAN_NL_MSG_OEM, __oem_msg_callback);
+}
+
#endif
diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_p2p.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_p2p.c
index d2225a4f2a6..feef357215b 100644
--- a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_p2p.c
+++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_p2p.c
@@ -132,10 +132,14 @@ static void hdd_sendMgmtFrameOverMonitorIface( hdd_adapter_t *pMonAdapter,
tANI_U8* pbFrames,
tANI_U8 frameType );
-static v_BOOL_t wlan_hdd_is_type_p2p_action( const u8 *buf )
+static v_BOOL_t wlan_hdd_is_type_p2p_action( const u8 *buf, uint32_t len )
{
const u8 *ouiPtr;
+ if (len < WLAN_HDD_PUBLIC_ACTION_FRAME_SUB_TYPE_OFFSET + 1) {
+ return VOS_FALSE;
+ }
+
if ( buf[WLAN_HDD_PUBLIC_ACTION_FRAME_CATEGORY_OFFSET] !=
WLAN_HDD_PUBLIC_ACTION_FRAME ) {
return VOS_FALSE;
@@ -160,11 +164,11 @@ static v_BOOL_t wlan_hdd_is_type_p2p_action( const u8 *buf )
return VOS_TRUE;
}
-static bool hdd_p2p_is_action_type_rsp( const u8 *buf )
+static bool hdd_p2p_is_action_type_rsp( const u8 *buf, uint32_t len )
{
tActionFrmType actionFrmType;
- if ( wlan_hdd_is_type_p2p_action(buf) )
+ if ( wlan_hdd_is_type_p2p_action(buf, len) )
{
actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_SUB_TYPE_OFFSET];
if ( actionFrmType != WLAN_HDD_INVITATION_REQ &&
@@ -1274,17 +1278,27 @@ int __wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev,
hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
- tANI_U8 type = WLAN_HDD_GET_TYPE_FRM_FC(buf[0]);
- tANI_U8 subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(buf[0]);
+ tANI_U8 type;
+ tANI_U8 subType;
tActionFrmType actionFrmType = WLAN_HDD_ACTION_FRM_TYPE_MAX;
bool noack = 0;
int status;
+ uint32_t mgmt_hdr_len = sizeof(struct ieee80211_hdr_3addr);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
uint8_t home_ch = 0;
#endif
ENTER();
+
+ if (len < mgmt_hdr_len + 1) {
+ hddLog(VOS_TRACE_LEVEL_ERROR,"Invalid Length");
+ return -EINVAL;
+ }
+
+ type = WLAN_HDD_GET_TYPE_FRM_FC(buf[0]);
+ subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(buf[0]);
+
MTRACE(vos_trace(VOS_MODULE_ID_HDD,
TRACE_CODE_HDD_ACTION, pAdapter->sessionId,
pAdapter->device_mode ));
@@ -1301,7 +1315,8 @@ int __wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev,
if ((type == SIR_MAC_MGMT_FRAME) &&
(subType == SIR_MAC_MGMT_ACTION) &&
- wlan_hdd_is_type_p2p_action(&buf[WLAN_HDD_PUBLIC_ACTION_FRAME_BODY_OFFSET]))
+ wlan_hdd_is_type_p2p_action(
+ &buf[WLAN_HDD_PUBLIC_ACTION_FRAME_BODY_OFFSET], len - mgmt_hdr_len))
{
actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET];
#ifdef WLAN_FEATURE_P2P_DEBUG
@@ -1600,7 +1615,9 @@ bypass_lock:
if ((type == SIR_MAC_MGMT_FRAME) &&
(subType == SIR_MAC_MGMT_ACTION) &&
- (buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_PUBLIC_ACTION_FRAME))
+ wlan_hdd_is_type_p2p_action(
+ &buf[WLAN_HDD_PUBLIC_ACTION_FRAME_BODY_OFFSET],
+ len - mgmt_hdr_len))
{
actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET];
hddLog(LOG1, "Tx Action Frame %u.", actionFrmType);
@@ -2461,7 +2478,9 @@ void __hdd_indicate_mgmt_frame(hdd_adapter_t *pAdapter,
/* Get pAdapter from Destination mac address of the frame */
if ((type == SIR_MAC_MGMT_FRAME) &&
- (subType != SIR_MAC_MGMT_PROBE_REQ))
+ (subType != SIR_MAC_MGMT_PROBE_REQ) &&
+ !vos_is_macaddr_broadcast(
+ (v_MACADDR_t *)&pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET]))
{
pAdapter = hdd_get_adapter_by_macaddr( WLAN_HDD_GET_CTX(pAdapter),
&pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET]);
@@ -2710,17 +2729,17 @@ void __hdd_indicate_mgmt_frame(hdd_adapter_t *pAdapter,
//Indicate Frame Over Normal Interface
hddLog( LOG1, FL("Indicate Frame over NL80211 Interface"));
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
- cfg80211_rx_mgmt(pAdapter->dev->ieee80211_ptr, freq, 0, pbFrames,
+ cfg80211_rx_mgmt(pAdapter->dev->ieee80211_ptr, freq, rxRssi * 100, pbFrames,
nFrameLength, NL80211_RXMGMT_FLAG_ANSWERED);
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
- cfg80211_rx_mgmt(pAdapter->dev->ieee80211_ptr, freq, 0, pbFrames,
+ cfg80211_rx_mgmt(pAdapter->dev->ieee80211_ptr, freq, rxRssi * 100, pbFrames,
nFrameLength, NL80211_RXMGMT_FLAG_ANSWERED, GFP_ATOMIC);
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
- cfg80211_rx_mgmt( pAdapter->dev->ieee80211_ptr, freq, 0,
+ cfg80211_rx_mgmt( pAdapter->dev->ieee80211_ptr, freq, rxRssi * 100,
pbFrames, nFrameLength,
GFP_ATOMIC );
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
- cfg80211_rx_mgmt( pAdapter->dev, freq, 0,
+ cfg80211_rx_mgmt( pAdapter->dev, freq, rxRssi * 100,
pbFrames, nFrameLength,
GFP_ATOMIC );
#else
diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_softap_tx_rx.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_softap_tx_rx.c
index 5a3f1de674b..2cb3b89887b 100644
--- a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_softap_tx_rx.c
+++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_softap_tx_rx.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -453,6 +453,23 @@ int __hdd_softap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
// checked. Over-limit packets will be dropped.
spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &pktListSize);
+
+ if (pHddCtx->bad_sta[STAId]) {
+ hdd_list_node_t *anchor = NULL;
+ skb_list_node_t *pktNode = NULL;
+ struct sk_buff *fskb = NULL;
+ if(pktListSize >= (pAdapter->aTxQueueLimit[ac])/2) {
+ hdd_list_remove_front(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac],
+ &anchor);
+ pktNode = list_entry(anchor, skb_list_node_t, anchor);
+ fskb = pktNode->skb;
+ kfree_skb(fskb);
+ pktListSize--;
+ ++pAdapter->stats.tx_dropped;
+ ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
+ }
+ }
+
if(pktListSize >= pAdapter->aTxQueueLimit[ac])
{
VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
@@ -740,7 +757,8 @@ void __hdd_softap_tx_timeout(struct net_device *dev)
hdd_context_t *pHddCtx;
VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
- "%s: Transmission timeout occurred", __func__);
+ "%s: Transmission timeout occurred jiffies %lu dev->trans_start %lu",
+ __func__, jiffies, dev->trans_start);
if ( NULL == pAdapter )
{
@@ -993,6 +1011,9 @@ static VOS_STATUS hdd_softap_flush_tx_queues_sta( hdd_adapter_t *pAdapter, v_U8_
spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock);
}
+ VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
+ "%s: flushed the TX queues of sta:%d", __func__, STAId);
+
return VOS_STATUS_SUCCESS;
}
@@ -1631,7 +1652,7 @@ VOS_STATUS hdd_softap_rx_packet_cbk( v_VOID_t *vosContext,
vos_pkt_t* pVosPacket;
vos_pkt_t* pNextVosPacket;
hdd_context_t *pHddCtx = NULL;
- v_U8_t proto_type;
+ v_U8_t proto_type = 0;
//Sanity check on inputs
if ( ( NULL == vosContext ) ||
diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_tdls.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_tdls.c
index 460ffe5637f..d17995429c2 100644
--- a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_tdls.c
+++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_tdls.c
@@ -3644,4 +3644,42 @@ void wlan_hdd_start_stop_tdls_source_timer(hdd_context_t *pHddCtx,
return;
}
+void wlan_hdd_get_tdls_stats(hdd_adapter_t *pAdapter)
+{
+ hdd_context_t *pHddCtx = NULL;
+ tdlsCtx_t *pHddTdlsCtx = NULL;
+ tANI_U16 numConnectedTdlsPeers = 0;
+ tANI_U16 numDiscoverySentCnt = 0;
+
+ pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
+
+ ENTER();
+ if (0 != (wlan_hdd_validate_context(pHddCtx)))
+ {
+ return;
+ }
+
+ pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
+
+ mutex_lock(&pHddCtx->tdls_lock);
+ if (NULL == pHddTdlsCtx)
+ {
+ mutex_unlock(&pHddCtx->tdls_lock);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ FL("pHddTdlsCtx points to NULL"));
+ return;
+ }
+ numConnectedTdlsPeers = pHddCtx->connected_peer_count;
+ numDiscoverySentCnt = pHddTdlsCtx->discovery_sent_cnt;
+ mutex_unlock(&pHddCtx->tdls_lock);
+
+ hddLog( LOGE, "%s: TDLS Mode: %d TDLS connected peer count %d"
+ " DiscoverySentCnt=%d", __func__, pHddCtx->tdls_mode,
+ numConnectedTdlsPeers, numDiscoverySentCnt);
+ EXIT();
+
+ return;
+}
+
+
/*EXT TDLS*/
diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_tx_rx.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_tx_rx.c
index 00ba6f40a13..b0a8c420133 100644
--- a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_tx_rx.c
+++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_tx_rx.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -840,11 +840,9 @@ int __hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (arp_pkt)
{
- if (pHddCtx->track_arp_ip && vos_check_arp_req_target_ip(skb, false)) {
- ++pAdapter->hdd_stats.hddArpStats.tx_arp_req_count;
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "%s :ARP packet received form net_dev", __func__);
- }
+ ++pAdapter->hdd_stats.hddArpStats.txCount;
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "%s :ARP packet received form net_dev", __func__);
}
//Get TL Q index corresponding to Qdisc queue index/AC.
@@ -933,6 +931,24 @@ int __hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_OK;
}
}
+
+ if (pHddCtx->bad_sta[STAId]) {
+ hdd_list_node_t *anchor = NULL;
+ skb_list_node_t *pktNode = NULL;
+ struct sk_buff *fskb = NULL;
+
+ if (pAdapter->wmm_tx_queue[qid].count >=
+ pAdapter->wmm_tx_queue[qid].max_size / 2) {
+ hdd_list_remove_front(&pAdapter->wmm_tx_queue[qid],
+ &anchor);
+ pktNode = list_entry(anchor, skb_list_node_t, anchor);
+ fskb = pktNode->skb;
+ kfree_skb(fskb);
+ ++pAdapter->stats.tx_dropped;
+ ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
+ }
+ }
+
//If we have already reached the max queue size, disable the TX queue
if ( pAdapter->wmm_tx_queue[qid].count == pAdapter->wmm_tx_queue[qid].max_size)
{
@@ -2676,9 +2692,8 @@ VOS_STATUS hdd_rx_packet_cbk( v_VOID_t *vosContext,
struct sk_buff *skb = NULL;
vos_pkt_t* pVosPacket;
vos_pkt_t* pNextVosPacket;
- v_U8_t proto_type;
+ v_U8_t proto_type = 0;
v_BOOL_t arp_pkt;
- bool track_arp_resp = false;
//Sanity check on inputs
if ( ( NULL == vosContext ) ||
@@ -2811,12 +2826,9 @@ VOS_STATUS hdd_rx_packet_cbk( v_VOID_t *vosContext,
if (arp_pkt)
{
- if (pHddCtx->track_arp_ip && vos_check_arp_rsp_src_ip(skb, false)) {
- ++pAdapter->hdd_stats.hddArpStats.rx_arp_rsp_count;
- track_arp_resp = true;
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "%s :STA RX ARP received",__func__);
- }
+ ++pAdapter->hdd_stats.hddArpStats.rxCount;
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "%s :STA RX ARP received",__func__);
}
if (pHddCtx->rx_wow_dump) {
@@ -2844,7 +2856,12 @@ VOS_STATUS hdd_rx_packet_cbk( v_VOID_t *vosContext,
pAdapter->stats.rx_bytes += skb->len;
if (arp_pkt)
- pAdapter->dad |= hdd_is_duplicate_ip_arp(skb);
+ {
+ pAdapter->dad = hdd_is_duplicate_ip_arp(skb);
+ if(pAdapter->dad)
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s :Duplicate IP detected",__func__);
+ }
#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
vos_wake_lock_timeout_release(&pHddCtx->rx_wake_lock,
HDD_WAKE_LOCK_DURATION,
@@ -2864,11 +2881,9 @@ VOS_STATUS hdd_rx_packet_cbk( v_VOID_t *vosContext,
if (arp_pkt)
{
- if (track_arp_resp) {
- ++pAdapter->hdd_stats.hddArpStats.rxDelivered;
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "STA RX ARP packet Delivered to net stack");
- }
+ ++pAdapter->hdd_stats.hddArpStats.rxDelivered;
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "STA RX ARP packet Delivered to net stack");
}
++pAdapter->hdd_stats.hddTxRxStats.rxDelivered;
@@ -3040,6 +3055,74 @@ void hdd_tx_rx_pkt_cnt_stat_timer_handler( void *phddctx)
return;
}
+/**
+ * hdd_rx_fwd_eapol() - forward cached eapol frames
+ * @vosContext : pointer to vos global context
+ * @pVosPacket: pointer to vos packet
+ *
+ * Return: None
+ *
+ */
+void hdd_rx_fwd_eapol(v_VOID_t *vosContext, vos_pkt_t *pVosPacket)
+{
+ hdd_context_t *pHddCtx = NULL;
+ hdd_adapter_t * pAdapter;
+ hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
+ struct sk_buff *skb = NULL;
+ uint8_t proto_type;
+ uint8_t status;
+
+ if ((NULL == vosContext) || (NULL == pVosPacket))
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
+ "%s: Null global context", __func__);
+ return;
+ }
+
+ pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vosContext);
+ if (NULL == pHddCtx)
+ {
+ VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
+ "%s: HDD adapter context is Null", __func__);
+ return;
+ }
+
+ status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
+
+ while ( NULL != pAdapterNode && 0 == status )
+ {
+ pAdapter = pAdapterNode->pAdapter;
+
+ if (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
+ break;
+
+ status = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
+ pAdapterNode = pNext;
+ }
+
+ if (NULL == pAdapter)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
+ "%s: No adapter", __func__);
+ return;
+ }
+
+ vos_pkt_get_os_packet(pVosPacket, (v_VOID_t **)&skb, VOS_FALSE);
+ proto_type = vos_pkt_get_proto_type(skb,
+ pHddCtx->cfg_ini->gEnableDebugLog);
+ if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "STA RX EAPOL");
+ }
+
+ skb->dev = pAdapter->dev;
+ skb->protocol = eth_type_trans(skb, skb->dev);
+ skb->ip_summed = CHECKSUM_NONE;
+
+ netif_rx_ni(skb);
+}
+
#ifdef FEATURE_WLAN_DIAG_SUPPORT
/*
* wlan_hdd_get_eapol_params() - Function to extract EAPOL params
diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_wext.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_wext.c
index 5cadb459d21..fbd52e7ef7d 100644
--- a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_wext.c
+++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_wext.c
@@ -174,6 +174,9 @@ static const hdd_freq_chan_map_t freq_chan_map[] = { {2412, 1}, {2417, 2},
#define WE_SET_MONITOR_STATE 22
#define WE_SET_PKT_STATS_ENABLE_DISABLE 23
#define WE_SET_PROXIMITY_ENABLE 24
+#define WE_CAP_TSF 25
+#define WE_SET_MODULATED_DTIM 26
+#define WLAN_SET_DYNNAMIC_AGGREGATION 27
/* Private ioctls and their sub-ioctls */
#define WLAN_PRIV_SET_NONE_GET_INT (SIOCIWFIRSTPRIV + 1)
@@ -295,7 +298,8 @@ static const hdd_freq_chan_map_t freq_chan_map[] = { {2412, 1}, {2417, 2},
/* (SIOCIWFIRSTPRIV + 10) is currently unused */
/* (SIOCIWFIRSTPRIV + 12) is currently unused */
/* (SIOCIWFIRSTPRIV + 14) is currently unused */
-/* (SIOCIWFIRSTPRIV + 15) is currently unused */
+#define WLAN_PRIV_SET_NONE_GET_THREE_INT (SIOCIWFIRSTPRIV + 15)
+#define WE_GET_TSF 1
#ifdef FEATURE_OEM_DATA_SUPPORT
/* Private ioctls for setting the measurement configuration */
@@ -387,6 +391,9 @@ static const hdd_freq_chan_map_t freq_chan_map[] = { {2412, 1}, {2417, 2},
#define TX_PWR_MAX 22
#define TX_PWR_DEF 50
+/* Dynamic Aggregation */
+#define DISABLE_AGGREGATION 0
+#define ENABLE_AGGREGATION 1
/*
* When supplicant sends SETBAND ioctl it queries for channels from
* cfg80211 layer by sending itself EVENT_CHANNEL_LIST_CHANGED command.
@@ -1107,6 +1114,8 @@ VOS_STATUS wlan_hdd_get_rssi(hdd_adapter_t *pAdapter, v_S7_t *rssi_value)
spin_unlock(&hdd_context_lock);
*rssi_value = pAdapter->rssi;
+ hddLog(VOS_TRACE_LEVEL_INFO,
+ "%s: RSSI = %d", __func__, *rssi_value);
return VOS_STATUS_SUCCESS;
}
@@ -1635,7 +1644,7 @@ v_U8_t* wlan_hdd_get_vendor_oui_ie_ptr(v_U8_t *oui, v_U8_t oui_size, v_U8_t *ie,
eid,elem_len,left);
return NULL;
}
- if (elem_id == eid)
+ if ((elem_id == eid) && (elem_len >= oui_size))
{
if(memcmp( &ptr[2], oui, oui_size)==0)
return ptr;
@@ -3584,10 +3593,12 @@ static void hdd_get_station_statisticsCB(void *pStats, void *pContext)
VOS_STATUS wlan_hdd_get_station_stats(hdd_adapter_t *pAdapter)
{
- hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
+ hdd_station_ctx_t *pHddStaCtx;
+ hdd_ap_ctx_t *sap_ctx;
eHalStatus hstatus;
long lrc;
struct statsContext context;
+ tANI_U8 sta_id;
if (NULL == pAdapter)
{
@@ -3595,6 +3606,14 @@ VOS_STATUS wlan_hdd_get_station_stats(hdd_adapter_t *pAdapter)
return VOS_STATUS_SUCCESS;
}
+ if (pAdapter->device_mode == WLAN_HDD_SOFTAP) {
+ sap_ctx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
+ sta_id = sap_ctx->uBCStaId;
+ } else {
+ pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
+ sta_id = pHddStaCtx->conn_info.staId[0];
+ }
+
/* we are connected
prepare our callback context */
init_completion(&context.completion);
@@ -3610,7 +3629,7 @@ VOS_STATUS wlan_hdd_get_station_stats(hdd_adapter_t *pAdapter)
hdd_get_station_statisticsCB,
0, // not periodic
FALSE, //non-cached results
- pHddStaCtx->conn_info.staId[0],
+ sta_id,
&context);
if (eHAL_STATUS_SUCCESS != hstatus)
{
@@ -3808,6 +3827,7 @@ static int iw_get_rssi(struct net_device *dev,
(note that it is not NUL-terminated) */
memcpy(cmd, pHddStaCtx->conn_info.SSID.SSID.ssId, ssidlen );
+ wlan_hdd_get_station_stats(pAdapter);
vosStatus = wlan_hdd_get_rssi(pAdapter, &s7Rssi);
if (VOS_STATUS_SUCCESS == vosStatus)
@@ -5572,7 +5592,7 @@ static int iw_set_mlme(struct net_device *dev,
return ret;
}
-int wlan_hdd_set_proximity(int set_value)
+int wlan_hdd_set_proximity(int set_value, tHalHandle hal)
{
sHwCalValues hwCalValues;
uint16 hwCalTxPower;
@@ -5593,12 +5613,14 @@ int wlan_hdd_set_proximity(int set_value)
txPwr = (int8)(hwCalTxPower & 0x00FF);
txPwr = txPwr/10;
- if (txPwr < TX_PWR_MIN)
+ if (txPwr == 0)
+ txPwr = TX_PWR_DEF;
+ else if (txPwr < TX_PWR_MIN)
txPwr = TX_PWR_MIN;
- if (txPwr > TX_PWR_MAX)
+ else if (txPwr > TX_PWR_MAX)
txPwr = TX_PWR_MAX;
- if (sme_SetMaxTxPowerPerBand(eCSR_BAND_24, txPwr) !=
+ if (sme_SetMaxTxPowerPerBand(eCSR_BAND_24, txPwr, hal) !=
eHAL_STATUS_SUCCESS) {
hddLog(VOS_TRACE_LEVEL_ERROR,
FL("Setting tx power failed for 2.4GHz band %d"), txPwr);
@@ -5607,12 +5629,14 @@ int wlan_hdd_set_proximity(int set_value)
txPwr = (int8)((hwCalTxPower >> 8) & 0x00FF);
txPwr /= 10;
- if (txPwr < TX_PWR_MIN)
+ if (txPwr == 0)
+ txPwr = TX_PWR_DEF;
+ else if (txPwr < TX_PWR_MIN)
txPwr = TX_PWR_MIN;
- if (txPwr > TX_PWR_MAX)
+ else if (txPwr > TX_PWR_MAX)
txPwr = TX_PWR_MAX;
- if (sme_SetMaxTxPowerPerBand(eCSR_BAND_5G, txPwr) !=
+ if (sme_SetMaxTxPowerPerBand(eCSR_BAND_5G, txPwr, hal) !=
eHAL_STATUS_SUCCESS) {
hddLog(VOS_TRACE_LEVEL_ERROR,
FL("setting tx power failed for 5GHz band %d"), txPwr);
@@ -5620,14 +5644,14 @@ int wlan_hdd_set_proximity(int set_value)
}
}
else if(FALSE == set_value) {
- if (sme_SetMaxTxPowerPerBand(eCSR_BAND_24, txPwr) !=
+ if (sme_SetMaxTxPowerPerBand(eCSR_BAND_24, txPwr, hal) !=
eHAL_STATUS_SUCCESS) {
hddLog(VOS_TRACE_LEVEL_ERROR,
FL("Setting tx power failed for 2.4GHz band %d"), txPwr);
return -EIO;
}
- if (sme_SetMaxTxPowerPerBand(eCSR_BAND_5G, txPwr) !=
+ if (sme_SetMaxTxPowerPerBand(eCSR_BAND_5G, txPwr, hal) !=
eHAL_STATUS_SUCCESS) {
hddLog(VOS_TRACE_LEVEL_ERROR,
FL("setting tx power failed for 5GHz band %d"), txPwr);
@@ -5640,6 +5664,42 @@ int wlan_hdd_set_proximity(int set_value)
return eHAL_STATUS_SUCCESS;
}
+
+static int hdd_set_dynamic_aggregation(int value, hdd_adapter_t *adapter)
+{
+ int ret = 0;
+ tHalHandle hal = WLAN_HDD_GET_HAL_CTX(adapter);
+ tDelBaParams del_session;
+
+ del_session.session_id = adapter->sessionId;
+ hddLog(LOG1, FL("WLAN_SET_DYNNAMIC_AGGREGATION: %d"), value);
+
+ if ((value == DISABLE_AGGREGATION) || (value == ENABLE_AGGREGATION))
+ {
+ ret = ccmCfgSetInt(hal, WNI_CFG_ENABLE_TX_RX_AGGREGATION,
+ value,NULL, eANI_BOOLEAN_FALSE);
+ if (ret != eHAL_STATUS_SUCCESS)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ FL("failed to set ini parameter, WNI_CFG_ENABLE_TX_RX_AGGREGATION"));
+ return -EIO;
+ }
+
+ } else {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ FL("Invalid command input"));
+ return -EINVAL;
+ }
+ ret = sme_del_sta_ba_session_req(hal, del_session);
+ if (ret != VOS_STATUS_SUCCESS) {
+ hddLog(VOS_TRACE_LEVEL_ERROR, FL("send ba session req fail"));
+ return -EINVAL;
+ }
+
+ EXIT();
+ return ret;
+}
+
/* set param sub-ioctls */
static int __iw_setint_getnone(struct net_device *dev,
struct iw_request_info *info,
@@ -5994,10 +6054,13 @@ static int __iw_setint_getnone(struct net_device *dev,
}
case WE_SET_MAX_TX_POWER_2_4:
{
+ if (NULL == hHal)
+ return -EINVAL;
+
hddLog(VOS_TRACE_LEVEL_INFO,
"%s: Setting maximum tx power %d dBm for 2.4 GHz band",
__func__, set_value);
- if (sme_SetMaxTxPowerPerBand(eCSR_BAND_24, set_value) !=
+ if (sme_SetMaxTxPowerPerBand(eCSR_BAND_24, set_value, hHal) !=
eHAL_STATUS_SUCCESS)
{
hddLog(VOS_TRACE_LEVEL_ERROR,
@@ -6010,10 +6073,13 @@ static int __iw_setint_getnone(struct net_device *dev,
}
case WE_SET_MAX_TX_POWER_5_0:
{
+ if (NULL == hHal)
+ return -EINVAL;
+
hddLog(VOS_TRACE_LEVEL_INFO,
"%s: Setting maximum tx power %d dBm for 5.0 GHz band",
__func__, set_value);
- if (sme_SetMaxTxPowerPerBand(eCSR_BAND_5G, set_value) !=
+ if (sme_SetMaxTxPowerPerBand(eCSR_BAND_5G, set_value, hHal) !=
eHAL_STATUS_SUCCESS)
{
hddLog(VOS_TRACE_LEVEL_ERROR,
@@ -6317,7 +6383,38 @@ static int __iw_setint_getnone(struct net_device *dev,
}
case WE_SET_PROXIMITY_ENABLE:
{
- ret = wlan_hdd_set_proximity(set_value);
+ if (NULL == hHal)
+ return -EINVAL;
+
+ ret = wlan_hdd_set_proximity(set_value, hHal);
+ break;
+ }
+ case WE_CAP_TSF:
+ {
+ if (NULL == hHal)
+ return -EINVAL;
+
+ ret = hdd_capture_tsf(pAdapter, (uint32_t *)&set_value, 1);
+ break;
+ }
+ case WE_SET_MODULATED_DTIM:
+ {
+ if ((set_value < CFG_ENABLE_MODULATED_DTIM_MIN) ||
+ (set_value > CFG_ENABLE_MODULATED_DTIM_MAX)) {
+ hddLog(LOGE, FL("Invalid value %d in gEnableModuleDTIM"),
+ set_value);
+ return -EINVAL;
+ } else {
+ ret = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->
+ enableModulatedDTIM = set_value;
+ }
+ }
+ case WLAN_SET_DYNNAMIC_AGGREGATION:
+ {
+ if (NULL == hHal)
+ return -EINVAL;
+
+ ret = hdd_set_dynamic_aggregation(set_value, pAdapter);
break;
}
default:
@@ -7020,10 +7117,10 @@ static int __iw_get_char_setnone(struct net_device *dev,
pResetStats->totalFWHearbeatFailures,
pResetStats->totalUnknownExceptions,
- parpStats->tx_arp_req_count,
+ parpStats->txCount,
parpStats->txDropped,
- parpStats->rx_arp_rsp_count,
+ parpStats->rxCount,
parpStats->rxDropped,
parpStats->rxDelivered,
parpStats->rxRefused,
@@ -8480,6 +8577,62 @@ static int iw_get_tspec(struct net_device *dev,
return ret;
}
+/**
+ * __iw_setnone_get_threeint() - return three value to up layer.
+ *
+ * @dev: pointer of net_device of this wireless card
+ * @info: meta data about Request sent
+ * @wrqu: include request info
+ * @extra: buf used for in/Output
+ *
+ * Return: execute result
+ */
+static int __iw_setnone_get_threeint(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ int ret = 0; /* success */
+ uint32_t *value = (int *)extra;
+ hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+
+ hddLog(VOS_TRACE_LEVEL_INFO, FL("param = %d"), value[0]);
+
+ switch (value[0]) {
+ case WE_GET_TSF:
+ ret = hdd_indicate_tsf(adapter, value, 3);
+ break;
+ default:
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ FL("Invalid IOCTL get_value command %d"),
+ value[0]);
+ break;
+ }
+ return ret;
+}
+
+/**
+ * iw_setnone_get_threeint() - return three value to up layer.
+ *
+ * @dev: pointer of net_device of this wireless card
+ * @info: meta data about Request sent
+ * @wrqu: include request info
+ * @extra: buf used for in/Output
+ *
+ * Return: execute result
+ */
+static int iw_setnone_get_threeint(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ int ret;
+
+ vos_ssr_protect(__func__);
+ ret = __iw_setnone_get_threeint(dev, info, wrqu, extra);
+ vos_ssr_unprotect(__func__);
+
+ return ret;
+}
+
#ifdef WLAN_FEATURE_VOWIFI_11R
//
//
@@ -10909,7 +11062,6 @@ int iw_set_tdlsoffchannelmode(hdd_adapter_t *pAdapter, int offchanmode)
}
#endif
-
// Define the Wireless Extensions to the Linux Network Device structure
// A number of these routines are NULL (meaning they are not implemented.)
@@ -10984,6 +11136,8 @@ static const iw_handler we_private[] = {
[WLAN_PRIV_ADD_TSPEC - SIOCIWFIRSTPRIV] = iw_add_tspec,
[WLAN_PRIV_DEL_TSPEC - SIOCIWFIRSTPRIV] = iw_del_tspec,
[WLAN_PRIV_GET_TSPEC - SIOCIWFIRSTPRIV] = iw_get_tspec,
+ [WLAN_PRIV_SET_NONE_GET_THREE_INT - SIOCIWFIRSTPRIV] =
+ iw_setnone_get_threeint,
#ifdef FEATURE_OEM_DATA_SUPPORT
[WLAN_PRIV_SET_OEM_DATA_REQ - SIOCIWFIRSTPRIV] = iw_set_oem_data_req, //oem data req Specifc
[WLAN_PRIV_GET_OEM_DATA_RSP - SIOCIWFIRSTPRIV] = iw_get_oem_data_rsp, //oem data req Specifc
@@ -11146,6 +11300,20 @@ static const struct iw_priv_args we_private_args[] = {
{ WE_SET_PROXIMITY_ENABLE,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
0, "setProximity" },
+
+#ifdef WLAN_FEATURE_TSF
+ { WE_CAP_TSF,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0, "cap_tsf" },
+#endif
+ { WE_SET_MODULATED_DTIM,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0, "setModDTIM" },
+ {
+ WLAN_SET_DYNNAMIC_AGGREGATION,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0, "setAggregation" },
+
/* handlers for main ioctl */
{ WLAN_PRIV_SET_NONE_GET_INT,
0,
@@ -11502,7 +11670,17 @@ static const struct iw_priv_args we_private_args[] = {
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
"getTspec" },
-
+ /* handlers for main ioctl */
+ { WLAN_PRIV_SET_NONE_GET_THREE_INT,
+ 0,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
+ "" },
+#ifdef WLAN_FEATURE_TSF
+ { WE_GET_TSF,
+ 0,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
+ "get_tsf" },
+#endif
#ifdef FEATURE_OEM_DATA_SUPPORT
/* handlers for main ioctl - OEM DATA */
{
@@ -11577,6 +11755,10 @@ static const struct iw_priv_args we_private_args[] = {
WLAN_GET_LINK_SPEED,
IW_PRIV_TYPE_CHAR | 18,
IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed" },
+ {
+ WLAN_PRIV_SET_FTIES,
+ IW_PRIV_TYPE_CHAR | MAX_FTIE_SIZE,
+ 0, "set_ft_ies"},
};
diff --git a/drivers/staging/prima/CORE/MAC/inc/aniGlobal.h b/drivers/staging/prima/CORE/MAC/inc/aniGlobal.h
index 6c4d59bea0b..5257cfb6981 100644
--- a/drivers/staging/prima/CORE/MAC/inc/aniGlobal.h
+++ b/drivers/staging/prima/CORE/MAC/inc/aniGlobal.h
@@ -44,12 +44,6 @@
#ifndef _ANIGLOBAL_H
#define _ANIGLOBAL_H
-// Take care to avoid redefinition of this type, if it is
-// already defined in "halWmmApi.h"
-#if !defined(_HALMAC_WMM_API_H)
-typedef struct sAniSirGlobal *tpAniSirGlobal;
-#endif
-
#include "halTypes.h"
#include "sirCommon.h"
#include "aniSystemDefs.h"
@@ -230,6 +224,11 @@ typedef struct sLimTimers
TX_TIMER gLimFTPreAuthRspTimer;
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+ TX_TIMER glim_pre_auth_mbb_rsp_timer;
+ TX_TIMER glim_reassoc_mbb_rsp_timer;
+#endif
+
#ifdef FEATURE_WLAN_ESE
TX_TIMER gLimEseTsmTimer;
#endif
@@ -260,12 +259,6 @@ typedef struct {
v_TIME_t failed_timestamp[MAX_TIDS];
} tLimStaBAInfo;
-typedef struct {
- bool tx_aggr;
- uint8_t sta_id;
- uint8_t tid;
-} t_test_status_bainfo;
-
typedef struct sAniSirLim
{
////////////////////////////////////// TIMER RELATED START ///////////////////////////////////////////
@@ -920,7 +913,6 @@ tLimMlmOemDataRsp *gpLimMlmOemDataRsp;
tANI_U32 txBdToken;
tANI_U32 EnableTdls2040BSSCoexIE;
tLimStaBAInfo staBaInfo[WLAN_MAX_STA_COUNT];
- t_test_status_bainfo test_status_bainfo;
} tAniSirLim, *tpAniSirLim;
typedef struct sLimMgmtFrameRegistration
@@ -948,6 +940,14 @@ typedef struct sFTContext
} tftContext, *tpFTContext;
#endif
+typedef struct assoc_rsp_tx_context
+{
+ vos_list_node_t node;
+ tANI_U8 psessionID;
+ tANI_U16 staId;
+ tANI_U32 txBdToken;
+} assoc_rsp_tx_context;
+
//Check if this definition can actually move here even for Volans. In that case
//this featurization can be removed.
/** ------------------------------------------------------------------------- *
@@ -1052,7 +1052,7 @@ typedef struct sAniSirGlobal
#if defined WLAN_FEATURE_VOWIFI_11R
tftContext ft;
#endif
-
+ vos_list_t assoc_rsp_completion_list;
tANI_U32 gCurrentLogSize;
tANI_U32 menuCurrent;
/* logDump specific */
@@ -1093,7 +1093,12 @@ typedef struct sAniSirGlobal
v_U32_t PERroamTimeout;
v_U32_t currentBssScore;
#endif
+#ifdef SAP_AUTH_OFFLOAD
+ bool sap_auth_offload;
+ uint32_t sap_auth_offload_sec_type;
+#endif /* SAP_AUTH_OFFLOAD */
bool max_power_cmd_pending;
+ uint32_t sta_auth_retries_for_code17;
} tAniSirGlobal;
#ifdef FEATURE_WLAN_TDLS
diff --git a/drivers/staging/prima/CORE/MAC/inc/qwlan_version.h b/drivers/staging/prima/CORE/MAC/inc/qwlan_version.h
index d49b49462d9..07a6af758a8 100644
--- a/drivers/staging/prima/CORE/MAC/inc/qwlan_version.h
+++ b/drivers/staging/prima/CORE/MAC/inc/qwlan_version.h
@@ -44,8 +44,8 @@ BRIEF DESCRIPTION:
#define QWLAN_VERSION_PATCH 11
#define QWLAN_VERSION_EXTRA ""
-#define QWLAN_VERSION_BUILD 66
+#define QWLAN_VERSION_BUILD 85
-#define QWLAN_VERSIONSTR "3.0.11.66"
+#define QWLAN_VERSIONSTR "3.0.11.85"
#endif /* QWLAN_VERSION_H */
diff --git a/drivers/staging/prima/CORE/MAC/inc/sirApi.h b/drivers/staging/prima/CORE/MAC/inc/sirApi.h
index f1d59c42b08..de0f9cc7ebb 100644
--- a/drivers/staging/prima/CORE/MAC/inc/sirApi.h
+++ b/drivers/staging/prima/CORE/MAC/inc/sirApi.h
@@ -41,10 +41,18 @@
#ifndef __SIR_API_H
#define __SIR_API_H
+/* Take care to avoid redefinition of this type, if it is */
+/* already defined in "halWmmApi.h" */
+#if !defined(_HALMAC_WMM_API_H)
+typedef struct sAniSirGlobal *tpAniSirGlobal;
+#endif
+
+
#include "sirTypes.h"
#include "sirMacProtDef.h"
#include "aniSystemDefs.h"
#include "sirParams.h"
+#include <dot11f.h>
#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD)
#include "eseGlobal.h"
@@ -756,6 +764,13 @@ typedef struct sSirSmeStartBssRsp
tSirBssDescription bssDescription;//Peer BSS description
} tSirSmeStartBssRsp, *tpSirSmeStartBssRsp;
+#ifdef WLAN_FEATURE_APFIND
+struct hal_apfind_request
+{
+ tANI_U16 request_data_len;
+ tANI_U8 request_data[];
+};
+#endif
typedef struct sSirChannelList
{
@@ -1110,6 +1125,7 @@ typedef struct sSirSmeJoinReq
tAniBool spectrumMgtIndicator;
tSirMacPowerCapInfo powerCap;
tSirSupChnl supportedChannels;
+ bool force_24ghz_in_ht20;
tSirBssDescription bssDescription;
} tSirSmeJoinReq, *tpSirSmeJoinReq;
@@ -1149,6 +1165,12 @@ typedef struct sSirSmeJoinRsp
/*to report MAX link-speed populate rate-flags from ASSOC RSP frame*/
tANI_U32 maxRateFlags;
+ tDot11fIEHTCaps ht_caps;
+ tDot11fIEVHTCaps vht_caps;
+ tDot11fIEHTInfo ht_operation;
+ tDot11fIEVHTOperation vht_operation;
+ tDot11fIEhs20vendor_ie hs20vendor_ie;
+
tANI_U8 frames[ 1 ];
} tSirSmeJoinRsp, *tpSirSmeJoinRsp;
@@ -2928,10 +2950,11 @@ typedef struct sSmeDelBAPeerInd
// Message Type
tANI_U16 mesgType;
+ tSirMacAddr bssId;//BSSID
+
// Message Length
tANI_U16 mesgLen;
- tSirMacAddr bssId;//BSSID
// Station Index
tANI_U16 staIdx;
@@ -3751,9 +3774,13 @@ typedef struct sSirNoAParam
tANI_U8 psSelection;
}tSirNoAParam, *tpSirNoAParam;
+typedef void(*wlan_suspend_req_cb)(void *ptr, VOS_STATUS status);
+
typedef struct sSirWlanSuspendParam
{
tANI_U8 configuredMcstBcstFilterSetting;
+ wlan_suspend_req_cb wlan_sus_callback;
+ void *context;
}tSirWlanSuspendParam,*tpSirWlanSuspendParam;
typedef struct sSirWlanResumeParam
@@ -3834,11 +3861,17 @@ typedef struct {
void *data_ctx;
} getArpStatsParams, *pgetArpStatsParams;
+
typedef void(*FWLoggingInitReqCb)(void *fwlogInitCbContext, tAniLoggingInitRsp *pRsp);
typedef void ( *tGetFrameLogCallback) (void *pContext);
typedef void(*RssiMonitorReqCb)(void *rssiMonitorCbContext, VOS_STATUS status);
typedef void(*pktFilterReqCb)(void *data, tANI_U32 status);
-
+typedef void(*dhcp_offload_req_cb)(void *rssiMonitorCbContext,
+ VOS_STATUS status);
+typedef void(*mdns_enable_req_cb)(void *mdns_enable_cb_context,
+ VOS_STATUS status);
+typedef void(*mdns_fqdn_req_cb)(void *mdns_fqdn_cb_context, VOS_STATUS status);
+typedef void(*mdns_resp_req_cb)(void *mdns_resp_cb_context, VOS_STATUS status);
typedef struct sAniGetFrameLogReq
{
@@ -4100,6 +4133,7 @@ typedef struct sSirRoamOffloadScanReq
tANI_U8 p5GProbeTemplate[SIR_ROAM_SCAN_MAX_PB_REQ_SIZE];
tANI_U8 nProbes;
tANI_U16 HomeAwayTime;
+ tANI_U8 WeakZoneRssiThresholdForRoam;
tSirRoamNetworkType ConnectedNetwork;
tSirMobilityDomainInfo MDID;
} tSirRoamOffloadScanReq, *tpSirRoamOffloadScanReq;
@@ -5612,6 +5646,65 @@ typedef PACKED_PRE struct PACKED_POST
tSirWifiScanResult bssHotlist[1];
} tSirEXTScanHotlistMatch, *tpSirEXTScanHotlistMatch;
+#ifdef DHCP_SERVER_OFFLOAD
+/**
+ * sir_dhcp_srv_offload_info_t - dhcp server offload info
+ * @bssidx: bss index
+ * @dhcp_srv_offload_enabled: enable or disable
+ * @dhcp_client_num: number of clients supported
+ * @dhcp_srv_ip: server ip address
+ * @start_lsb: lsb of start address of dhcp pool
+ */
+typedef struct
+{
+ tANI_U8 bssidx;
+ tANI_U32 dhcp_srv_offload_enabled;
+ tANI_U32 dhcp_client_num;
+ tANI_U32 dhcp_srv_ip;
+ tANI_U32 start_lsb;
+ dhcp_offload_req_cb dhcp_offload_callback;
+ void *dhcp_server_offload_cb_context;
+} sir_dhcp_srv_offload_info_t, *sir_dhcp_srv_offload_info;
+#endif /* DHCP_SERVER_OFFLOAD */
+
+#ifdef MDNS_OFFLOAD
+#define MAX_MDNS_FQDN_LEN 64
+#define MAX_MDNS_RESP_LEN 512
+
+typedef struct
+{
+ tANI_U8 bss_idx;
+ tANI_U32 enable;
+ mdns_enable_req_cb mdns_enable_callback;
+ void *mdns_enable_cb_context;
+} sir_mdns_offload_info_t, *sir_mdns_offload_info;
+
+typedef struct
+{
+ tANI_U8 bss_idx;
+ tANI_U32 fqdn_type;
+ tANI_U32 fqdn_len;
+ tANI_U8 fqdn_data[MAX_MDNS_FQDN_LEN];
+ mdns_fqdn_req_cb mdns_fqdn_callback;
+ void *mdns_fqdn_cb_context;
+
+} sir_mdns_fqdn_info_t, *sir_mdns_fqdn_info;
+
+typedef struct
+{
+ tANI_U8 bss_idx;
+ tANI_U32 resourceRecord_count;
+ tANI_U32 resp_len;
+ tANI_U8 resp_data[MAX_MDNS_RESP_LEN];
+ mdns_resp_req_cb mdns_resp_callback;
+ void *mdns_resp_cb_context;
+} sir_mdns_resp_info_t, *sir_mdns_resp_info;
+
+typedef struct
+{
+ tANI_U8 bss_idx;
+} sir_get_mdns_stats_info_t, *sir_get_mdns_stats_info;
+#endif /* MDNS_OFFLOAD */
typedef PACKED_PRE struct PACKED_POST
{
@@ -6050,11 +6143,188 @@ typedef struct {
tANI_U32 value;
} tModifyRoamParamsReqParams, * tpModifyRoamParamsReqParams;
-typedef void(*hdd_conAliveCb)(void *data, bool status);
+#ifdef SAP_AUTH_OFFLOAD
+/* 80211 Pre-Share Key length */
+#define SIR_PSK_MAX_LEN 64
+/**
+ * enum tSirSecurityType - definition for Software AP Auth Offload
+ * Security Type
+ * @eSIR_OFFLOAD_NONE: None type security
+ * @eSIR_OFFLOAD_WPA2PSK_CCMP: WPA2-PSK
+ */
+enum tSirSecurityType
+{
+ eSIR_OFFLOAD_NONE,
+ eSIR_OFFLOAD_WPA2PSK_CCMP,
+};
+
+/**
+ * struct tSirSapOffloadInfo - Structure to store sap offload related params.
+ * @macAddr: Self mac address
+ * @sap_auth_offload_enable: tell if sap auth offload is enabled or not.
+ * @sap_auth_offload_sec_type: tells security type
+ * 0 - none
+ * 1 - WPA1-PSK
+ * @key_len: psk key length
+ * @key: psk key.
+ */
+struct tSirSapOffloadInfo
+{
+ tSirMacAddr macAddr;
+ bool sap_auth_offload_enable;
+ uint32_t sap_auth_offload_sec_type;
+ uint32_t key_len;
+ uint8_t key[SIR_PSK_MAX_LEN];
+};
+
+typedef PACKED_PRE struct PACKED_POST
+{
+ /** staId returned from firmware for each STA association to SAP */
+ tANI_U8 staIdx;
+ /** bssIdx on which the STA is added */
+ tANI_U8 bssIdx;
+ /** DPU desc index of this station */
+ tANI_U8 dpuIndex;
+ /** Bcast DPU index of this station */
+ tANI_U8 bcastDpuIndex;
+ /** Bcast DPU Management index of this station */
+ tANI_U8 bcastMgmtDpuIdx;
+
+ tANI_U8 ucUcastSig;
+
+ tANI_U8 ucBcastSig;
+
+ tANI_U8 ucMgmtSig;
+ /** aid (association id) of this station */
+ tANI_U32 assoc_id;
+ /** peer station's mac addr */
+ tSirMacAddr peer_macaddr;
+ /** length of association request frame */
+ tANI_U32 data_len;
+ /* Following this structure is the byte stream of a whole
+ * association request frame of length data_len
+ */
+ tANI_U8 bufp[1];
+} tSapOfldAddStaIndMsg, *tpSapOfldAddStaIndMsg;
+
+typedef enum
+{
+ SAP_OFL_DEL_STA_FLAG_NONE = 0x00,
+ SAP_OFL_DEL_STA_FLAG_RECONNECT = 0x01,
+} eSapOfldDelStaFlags;
+
+typedef PACKED_PRE struct PACKED_POST
+{
+ tANI_U32 staIdx;
+ /** bssIdx on which the STA is added */
+ tANI_U32 bssIdx;
+ /** aid (association id) of this station */
+ tANI_U32 assoc_id;
+ /** peer station's mac addr */
+ tSirMacAddr peer_macaddr;
+ /** disassociation reason */
+ tANI_U32 reason;
+ /** flags - wmi_sap_ofl_del_sta_flags */
+ tANI_U32 flags;
+} tSapOfldDelStaIndMsg, *tpSapOfldDelStaIndMsg;
+
+typedef enum
+{
+ SAP_OFFLOAD_ADD_STA_IND = 0x00,
+ SAP_OFFLOAD_DEL_STA_IND = 0x01,
+} eSapOfldIndType;
+
+typedef PACKED_PRE struct PACKED_POST
+{
+ /* indType will be from eSapOfldIndType */
+ tANI_U32 indType;
+ /* size of this array will be depend on the indication type.
+ * Indication type can be either ADD_STA_IND or DEL_STA_IND.
+ * If indication type is ADD_STA_IND, size of this indication
+ * array will be sizeof(tSapOfldDelStaIndMsg)
+ * and if indication type is DEL_STA_IND, size of this indication
+ * arrary will be sizeof(tSapOfldAddStaIndMsg)
+ */
+ tANI_U8 indication[1];
+} tSapOfldInd;
+
+typedef PACKED_PRE struct PACKED_POST
+{
+ tANI_U32 num_indications;
+ /* size of this array will be depend on the number of indications.*/
+ tSapOfldInd indications[1];
+}tSapOfldIndications;
+
+#endif /* SAP_AUTH_OFFLOAD */
+
+/**
+ * struct stsf - the basic stsf structure
+ *
+ * @session_id: session id from adapter
+ * @set_req: set/get request flag.
+ * @tsf_low: low 32bits of tsf
+ * @tsf_high: high 32bits of tsf
+ *
+ * driver use this struct to store the tsf info
+ */
+struct stsf {
+ uint32_t session_id;
+ bool set_tsf_req;
+ uint32_t tsf_low;
+ uint32_t tsf_high;
+ bool tsf_req_status;
+};
+
+typedef int(*tsf_rsp_cb)(void *tsf_ctx, struct stsf *pTsf);
+
+/**
+ * struct tCapTsfParams - capture tsf request
+ * @bss_idx: bss index, SAP/STA
+ * @session_id: adapter session id
+ * @bssid: bssid for SAP/STA
+ * @tsf_rsp_cb_func : handler for tsf rsp from fw
+ * @tsf_rsp_cb_ctx : hdd ctx for tsf rsp handler
+ */
typedef struct {
- hdd_conAliveCb rsp_cb_fn;
- void *data_ctx;
-}getConStatusParams, *pgetConStatusParams;
+ tANI_U8 bss_idx;
+ tANI_U8 session_id;
+ tSirMacAddr bssid;
+ tsf_rsp_cb tsf_rsp_cb_func;
+ void * tsf_rsp_cb_ctx;
+}tSirCapTsfParams,*tpSirCapTsfParams;
+
+#ifdef WLAN_FEATURE_LFR_MBB
+
+/**
+ * enum csr_roam_op_code - Operation to be done by the callback.
+ * @SIR_ROAMING_DEREGISTER_STA: Deregister the old STA after roaming.
+ * @SIR_STOP_ROAM_OFFLOAD_SCAN : sends RSO stop
+ * @SIR_PREPARE_REASSOC_REQ: prepares reassoc request
+ */
+enum csr_roam_op_code {
+ SIR_ROAMING_DEREGISTER_STA,
+ SIR_STOP_ROAM_OFFLOAD_SCAN,
+ SIR_PREPARE_REASSOC_REQ,
+};
+
+/**
+ * enum sir_roam_cleanup_type - Type of cleanup needs to be performed.
+ * @SIR_MBB_DISCONNECTED: Entire CSR cleanup for connected AP
+ * needs to be performed
+ * @SIR_MBB_CONNECTED: No need to perform CSR cleanup for connected AP.
+ */
+enum sir_roam_cleanup_type {
+ SIR_MBB_DISCONNECTED,
+ SIR_MBB_CONNECTED,
+};
+#endif
+/**
+ * struct tDelBaParams - Del BA Session req
+ * @session_id: adapter session id
+ */
+typedef struct {
+ tANI_U8 session_id;
+}tDelBaParams,*ptDelBaParams;
#endif /* __SIR_API_H */
diff --git a/drivers/staging/prima/CORE/MAC/inc/sirMacProtDef.h b/drivers/staging/prima/CORE/MAC/inc/sirMacProtDef.h
index 75c73e44102..52c172a78d7 100644
--- a/drivers/staging/prima/CORE/MAC/inc/sirMacProtDef.h
+++ b/drivers/staging/prima/CORE/MAC/inc/sirMacProtDef.h
@@ -598,8 +598,13 @@
#define SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS 4
#define SIR_MAC_KEY_LENGTH 13 // WEP Maximum key length size
#define SIR_MAC_AUTH_CHALLENGE_LENGTH 253
+#define SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH 128
#define SIR_MAC_WEP_IV_LENGTH 4
#define SIR_MAC_WEP_ICV_LENGTH 4
+#define SIR_MAC_CHALLENGE_ID_LEN 2
+
+/* 2 bytes each for auth algo number, transaction number and status code */
+#define SIR_MAC_AUTH_FRAME_INFO_LEN 6
/// MAX key length when ULA is used
#define SIR_MAC_MAX_KEY_LENGTH 32
diff --git a/drivers/staging/prima/CORE/MAC/inc/wniApi.h b/drivers/staging/prima/CORE/MAC/inc/wniApi.h
index bdea77c7c0c..6445286ce06 100644
--- a/drivers/staging/prima/CORE/MAC/inc/wniApi.h
+++ b/drivers/staging/prima/CORE/MAC/inc/wniApi.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2013, 2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 2016-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -235,7 +235,6 @@ enum eWniMsgTypes
eWNI_SME_PRE_CHANNEL_SWITCH_FULL_POWER,
eWNI_SME_GET_SNR_REQ,
eWNI_SME_LOST_LINK_PARAMS_IND,
- eWNI_SME_DEL_TEST_BA,
//General Power Save Messages
eWNI_PMC_MSG_TYPES_BEGIN,
eWNI_PMC_PWR_SAVE_CFG,
@@ -388,6 +387,15 @@ enum eWniMsgTypes
eWNI_SME_SET_TDLS_2040_BSSCOEX_REQ,
eWNI_SME_DEL_ALL_TDLS_PEERS,
eWNI_SME_REGISTER_MGMT_FRAME_CB,
+ eWNI_SME_CAP_TSF_REQ,
+ eWNI_SME_GET_TSF_REQ,
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ eWNI_SME_MBB_PRE_AUTH_REASSOC_REQ,
+ eWNI_SME_MBB_PRE_AUTH_REASSOC_RSP,
+#endif
+
+ eWNI_SME_DEL_BA_SES_REQ,
eWNI_SME_MSG_TYPES_END
};
diff --git a/drivers/staging/prima/CORE/MAC/inc/wniCfg.h b/drivers/staging/prima/CORE/MAC/inc/wniCfg.h
index a6557506534..4db2054360c 100644
--- a/drivers/staging/prima/CORE/MAC/inc/wniCfg.h
+++ b/drivers/staging/prima/CORE/MAC/inc/wniCfg.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -394,7 +394,10 @@ enum {
WNI_CFG_SAR_BOFFSET_SET_CORRECTION,
WNI_CFG_ENABLE_UNITS_BWAIT,
WNI_CFG_ENABLE_CONC_BMISS,
- WNI_CFG_DISABLE_SCAN_DURING_SCO
+ WNI_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL,
+ WNI_CFG_DISABLE_SCAN_DURING_SCO,
+ WNI_CFG_ENABLE_TX_RX_AGGREGATION,
+ WNI_CFG_TRIGGER_NULLFRAME_BEFORE_HB
};
/*
@@ -760,7 +763,7 @@ enum {
#define WNI_CFG_MAX_NUM_PRE_AUTH_STADEF 64
#define WNI_CFG_HEART_BEAT_THRESHOLD_STAMIN 0
-#define WNI_CFG_HEART_BEAT_THRESHOLD_STAMAX 65535
+#define WNI_CFG_HEART_BEAT_THRESHOLD_STAMAX 256
#define WNI_CFG_HEART_BEAT_THRESHOLD_STADEF 40
#define WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT_STAMIN 10
@@ -1805,7 +1808,7 @@ enum {
#define WNI_CFG_RA_FILTER_ENABLE_STADEF 0
#define WNI_CFG_RA_RATE_LIMIT_INTERVAL_STAMIN 0
-#define WNI_CFG_RA_RATE_LIMIT_INTERVAL_STAMAX 60
+#define WNI_CFG_RA_RATE_LIMIT_INTERVAL_STAMAX 3600
#define WNI_CFG_RA_RATE_LIMIT_INTERVAL_STADEF 60
#define WNI_CFG_BTC_FATAL_HID_NSNIFF_BLK_GUIDANCE_STAMIN 0
@@ -1895,6 +1898,10 @@ enum {
#define WNI_CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN_MAX 250000
#define WNI_CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN_DEF 40000
+#define WNI_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_MIN 0
+#define WNI_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_MAX 1
+#define WNI_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_DEF 0
+
#define WNI_CFG_LINK_FAIL_TIMEOUT_MIN 1000
#define WNI_CFG_LINK_FAIL_TIMEOUT_MAX 60000
#define WNI_CFG_LINK_FAIL_TIMEOUT_DEF 6000
@@ -1931,8 +1938,16 @@ enum {
#define WNI_CFG_DISABLE_SCAN_DURING_SCO_MAX 1
#define WNI_CFG_DISABLE_SCAN_DURING_SCO_DEF 0
-#define CFG_PARAM_MAX_NUM 361
-#define CFG_STA_IBUF_MAX_SIZE 295
+#define WNI_CFG_ENABLE_TX_RX_AGGREGATION_MIN 0
+#define WNI_CFG_ENABLE_TX_RX_AGGREGATION_MAX 1
+#define WNI_CFG_ENABLE_TX_RX_AGGREGATION_DEF 1
+
+#define WNI_CFG_TRIGGER_NULLFRAME_BEFORE_HB_MIN 0
+#define WNI_CFG_TRIGGER_NULLFRAME_BEFORE_HB_MAX 1
+#define WNI_CFG_TRIGGER_NULLFRAME_BEFORE_HB_DEF 0
+
+#define CFG_PARAM_MAX_NUM 364
+#define CFG_STA_IBUF_MAX_SIZE 298
#define CFG_STA_SBUF_MAX_SIZE 3389
#define CFG_STA_MAGIC_DWORD 0xbeefbeef
diff --git a/drivers/staging/prima/CORE/MAC/src/cfg/cfgApi.c b/drivers/staging/prima/CORE/MAC/src/cfg/cfgApi.c
index 9047d3a7a21..b4c260b96b9 100644
--- a/drivers/staging/prima/CORE/MAC/src/cfg/cfgApi.c
+++ b/drivers/staging/prima/CORE/MAC/src/cfg/cfgApi.c
@@ -957,6 +957,17 @@ cfgGetCapabilityInfo(tpAniSirGlobal pMac, tANI_U16 *pCap,tpPESession sessionEntr
if(systemRole == eLIM_AP_ROLE)
{
val = sessionEntry->privacy;
+#ifdef SAP_AUTH_OFFLOAD
+ /* Support SAP Authentication Offload feature,
+ * If Auth offload security Type is not disabled
+ * driver need to enable privacy bit in beacon
+ */
+ if (pMac->sap_auth_offload && pMac->sap_auth_offload_sec_type)
+ {
+ val = 1;
+ }
+#endif
+
}
else
{
diff --git a/drivers/staging/prima/CORE/MAC/src/cfg/cfgProcMsg.c b/drivers/staging/prima/CORE/MAC/src/cfg/cfgProcMsg.c
index 999bd5976b7..43bcf084824 100644
--- a/drivers/staging/prima/CORE/MAC/src/cfg/cfgProcMsg.c
+++ b/drivers/staging/prima/CORE/MAC/src/cfg/cfgProcMsg.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -1703,6 +1703,16 @@ tAniSirCgStatic cfgStatic[CFG_PARAM_MAX_NUM] =
WNI_CFG_SAR_BOFFSET_SET_CORRECTION_MIN,
WNI_CFG_SAR_BOFFSET_SET_CORRECTION_MAX,
WNI_CFG_SAR_BOFFSET_SET_CORRECTION_DEFAULT},
+ {WNI_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL,
+ WNI_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_MIN,
+ WNI_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_MAX,
+ WNI_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_DEF},
+ {WNI_CFG_DISABLE_SCAN_DURING_SCO,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL,
+ WNI_CFG_DISABLE_SCAN_DURING_SCO_MIN,
+ WNI_CFG_DISABLE_SCAN_DURING_SCO_MAX,
+ WNI_CFG_DISABLE_SCAN_DURING_SCO_DEF},
{WNI_CFG_ENABLE_CONC_BMISS,
CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
WNI_CFG_ENABLE_CONC_BMISS_STAMIN,
@@ -1713,11 +1723,16 @@ tAniSirCgStatic cfgStatic[CFG_PARAM_MAX_NUM] =
WNI_CFG_ENABLE_UNITS_BWAIT_STAMIN,
WNI_CFG_ENABLE_UNITS_BWAIT_STAMAX,
WNI_CFG_ENABLE_UNITS_BWAIT_STADEF},
- {WNI_CFG_DISABLE_SCAN_DURING_SCO,
- CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL,
- WNI_CFG_DISABLE_SCAN_DURING_SCO_MIN,
- WNI_CFG_DISABLE_SCAN_DURING_SCO_MAX,
- WNI_CFG_DISABLE_SCAN_DURING_SCO_DEF},
+ {WNI_CFG_ENABLE_TX_RX_AGGREGATION,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_ENABLE_TX_RX_AGGREGATION_MIN,
+ WNI_CFG_ENABLE_TX_RX_AGGREGATION_MAX,
+ WNI_CFG_ENABLE_TX_RX_AGGREGATION_DEF},
+ {WNI_CFG_TRIGGER_NULLFRAME_BEFORE_HB,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_TRIGGER_NULLFRAME_BEFORE_HB_MIN,
+ WNI_CFG_TRIGGER_NULLFRAME_BEFORE_HB_MAX,
+ WNI_CFG_TRIGGER_NULLFRAME_BEFORE_HB_DEF},
};
tAniSirCfgStaticString cfgStaticString[CFG_MAX_STATIC_STRING] =
diff --git a/drivers/staging/prima/CORE/MAC/src/cfg/cfgUtil/dot11f.frms b/drivers/staging/prima/CORE/MAC/src/cfg/cfgUtil/dot11f.frms
index f4e490ac786..3c125e9e9bd 100644
--- a/drivers/staging/prima/CORE/MAC/src/cfg/cfgUtil/dot11f.frms
+++ b/drivers/staging/prima/CORE/MAC/src/cfg/cfgUtil/dot11f.frms
@@ -2047,6 +2047,28 @@ IE ESERadMgmtCap (EID_VENDOR_SPECIFIC) OUI (0x00, 0x40, 0x96, 0x01)
}
+IE hs20vendor_ie (EID_VENDOR_SPECIFIC) OUI (0x50, 0x6F, 0x9A, 0x10)
+{
+ /* hotspot_configurations */
+ {
+ dgaf_dis: 1;
+ hs_id_present: 2;
+ reserved: 1;
+ release_num: 4;
+ }
+ OPTIONAL UNION hs_id (DISCRIMINATOR hs_id_present)
+ {
+ pps_mo (hs_id_present IS 1)
+ {
+ pps_mo_id, 2;
+ }
+ anqp_domain (hs_id_present IS 2)
+ {
+ anqp_domain_id, 2;
+ }
+ };
+}
+
IE ESETrafStrmMet (EID_VENDOR_SPECIFIC) OUI (0x00, 0x40, 0x96, 0x07)
{
tsid, 1;
@@ -3334,6 +3356,7 @@ FRAME Beacon // C.f. Sec. 7.2.3.1
OPTIE OperatingMode;
OPTIE WiderBWChanSwitchAnn;
OPTIE OBSSScanParameters;
+ OPTIE hs20vendor_ie;
} // End frame Beacon.
// Ok, here's the story on Beacon1 & Beacon2. We presumably beacon a lot
@@ -3414,6 +3437,7 @@ FRAME Beacon2
OPTIE OperatingMode;
OPTIE WiderBWChanSwitchAnn;
OPTIE OBSSScanParameters;
+ OPTIE hs20vendor_ie;
}
// This frame is just Beacon with its Fixed Fields stripped out. It's handy
@@ -3471,6 +3495,7 @@ FRAME BeaconIEs
OPTIE OperatingMode;
OPTIE WiderBWChanSwitchAnn;
OPTIE OBSSScanParameters;
+ OPTIE hs20vendor_ie;
} // End frame BeaconIEs.
@@ -3508,6 +3533,7 @@ FRAME AssocRequest // 7.2.3.4
OPTIE ExtCap;
OPTIE OperatingMode;
OPTIE QosMapSet;
+ OPTIE hs20vendor_ie;
} // End frame AssocRequest.
FRAME AssocResponse // 7.2.3.5
@@ -3578,6 +3604,7 @@ FRAME ReAssocRequest // 7.2.3.6
OPTIE ExtCap;
OPTIE OperatingMode;
OPTIE QosMapSet;
+ OPTIE hs20vendor_ie;
} // End frame ReAssocRequest.
FRAME ReAssocResponse // 7.2.3.7
@@ -3676,6 +3703,7 @@ FRAME ProbeResponse // 7.2.3.9
OPTIE VHTExtBssLoad;
OPTIE ExtCap;
OPTIE OBSSScanParameters;
+ OPTIE hs20vendor_ie;
} // End frame ProbeResponse.
FRAME Authentication // 7.2.3.10
diff --git a/drivers/staging/prima/CORE/MAC/src/include/dot11f.h b/drivers/staging/prima/CORE/MAC/src/include/dot11f.h
index 50788d8af08..585d2b3151e 100644
--- a/drivers/staging/prima/CORE/MAC/src/include/dot11f.h
+++ b/drivers/staging/prima/CORE/MAC/src/include/dot11f.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014, 2016, 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -30,7 +30,7 @@
*
*
* This file was automatically generated by 'framesc'
- * Tue Jul 4 11:19:48 2017 from the following file(s):
+ * Wed Jul 12 16:02:49 2017 from the following file(s):
*
* dot11f.frms
*
@@ -6185,6 +6185,45 @@ tANI_U32 dot11fGetPackedIEWscReassocRes(tpAniSirGlobal, tDot11fIEWscReassocRes*,
#ifdef __cplusplus
}; /* End extern "C". */
#endif /* C++ */
+// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x10}
+typedef struct sDot11fIEhs20vendor_ie {
+ tANI_U8 present;
+ tANI_U8 dgaf_dis: 1;
+ tANI_U8 hs_id_present: 2;
+ tANI_U8 reserved: 1;
+ tANI_U8 release_num: 4;
+ union
+ {
+ struct
+ {
+ tANI_U16 pps_mo_id;
+ } pps_mo; /* hs_id_present = 1 */
+ struct
+ {
+ tANI_U16 anqp_domain_id;
+ } anqp_domain; /* hs_id_present = 2 */
+ } hs_id;
+} tDot11fIEhs20vendor_ie;
+
+#define DOT11F_EID_HS20VENDOR_IE ( 221 )
+
+// N.B. These #defines do *not* include the EID & length
+#define DOT11F_IE_HS20VENDOR_IE_MIN_LEN ( 5 )
+
+#define DOT11F_IE_HS20VENDOR_IE_MAX_LEN ( 7 )
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+tANI_U32 dot11fUnpackIehs20vendor_ie(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEhs20vendor_ie*);
+
+tANI_U32 dot11fPackIehs20vendor_ie(tpAniSirGlobal, tDot11fIEhs20vendor_ie*, tANI_U8*, tANI_U32, tANI_U32*);
+
+tANI_U32 dot11fGetPackedIEhs20vendor_ie(tpAniSirGlobal, tDot11fIEhs20vendor_ie*, tANI_U32*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
/************************************************************************
* Frames
**********************************************************************/
@@ -6325,6 +6364,7 @@ typedef struct sDot11fAssocRequest{
tDot11fIEExtCap ExtCap;
tDot11fIEOperatingMode OperatingMode;
tDot11fIEQosMapSet QosMapSet;
+ tDot11fIEhs20vendor_ie hs20vendor_ie;
} tDot11fAssocRequest;
#define DOT11F_ASSOCREQUEST ( 5 )
@@ -6465,6 +6505,7 @@ typedef struct sDot11fBeacon{
tDot11fIEOperatingMode OperatingMode;
tDot11fIEWiderBWChanSwitchAnn WiderBWChanSwitchAnn;
tDot11fIEOBSSScanParameters OBSSScanParameters;
+ tDot11fIEhs20vendor_ie hs20vendor_ie;
} tDot11fBeacon;
#define DOT11F_BEACON ( 8 )
@@ -6539,6 +6580,7 @@ typedef struct sDot11fBeacon2{
tDot11fIEOperatingMode OperatingMode;
tDot11fIEWiderBWChanSwitchAnn WiderBWChanSwitchAnn;
tDot11fIEOBSSScanParameters OBSSScanParameters;
+ tDot11fIEhs20vendor_ie hs20vendor_ie;
} tDot11fBeacon2;
#define DOT11F_BEACON2 ( 10 )
@@ -6601,6 +6643,7 @@ typedef struct sDot11fBeaconIEs{
tDot11fIEOperatingMode OperatingMode;
tDot11fIEWiderBWChanSwitchAnn WiderBWChanSwitchAnn;
tDot11fIEOBSSScanParameters OBSSScanParameters;
+ tDot11fIEhs20vendor_ie hs20vendor_ie;
} tDot11fBeaconIEs;
#define DOT11F_BEACONIES ( 11 )
@@ -7217,6 +7260,7 @@ typedef struct sDot11fProbeResponse{
tDot11fIEVHTExtBssLoad VHTExtBssLoad;
tDot11fIEExtCap ExtCap;
tDot11fIEOBSSScanParameters OBSSScanParameters;
+ tDot11fIEhs20vendor_ie hs20vendor_ie;
} tDot11fProbeResponse;
#define DOT11F_PROBERESPONSE ( 37 )
@@ -7403,6 +7447,7 @@ typedef struct sDot11fReAssocRequest{
tDot11fIEExtCap ExtCap;
tDot11fIEOperatingMode OperatingMode;
tDot11fIEQosMapSet QosMapSet;
+ tDot11fIEhs20vendor_ie hs20vendor_ie;
} tDot11fReAssocRequest;
#define DOT11F_REASSOCREQUEST ( 44 )
diff --git a/drivers/staging/prima/CORE/MAC/src/include/dphGlobal.h b/drivers/staging/prima/CORE/MAC/src/include/dphGlobal.h
index 3dac65ae0c1..e6e7d98878e 100644
--- a/drivers/staging/prima/CORE/MAC/src/include/dphGlobal.h
+++ b/drivers/staging/prima/CORE/MAC/src/include/dphGlobal.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2013, 2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2013, 2016-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -320,6 +320,27 @@ typedef struct sCfgTrafficClass {
} tCfgTrafficClass;
+/**
+ * struct parsed_ies: Parsed IE's of BSS capability
+ * @ht_caps: HT caps IE
+ * @vht_caps: VHT caps IE
+ * @ht_operation: HT operation IE
+ * @vht_operation: VHT operation IE
+ * @hs20vendor_ie: HS2.0 vendor IE
+ *
+ * This structure holds the parsed IE of connected BSS
+ * and this is not the intersection of BSS and STA
+ * capability. For example, if BSS supports 80 MHz
+ * and STA connects to BSS in 20 MHz, this structure
+ * holds 80 MHz as peer capability.
+ */
+struct parsed_ies {
+ tDot11fIEHTCaps ht_caps;
+ tDot11fIEVHTCaps vht_caps;
+ tDot11fIEHTInfo ht_operation;
+ tDot11fIEVHTOperation vht_operation;
+ tDot11fIEhs20vendor_ie hs20vendor_ie;
+};
/// STA state node
@@ -639,6 +660,13 @@ typedef struct sDphHashNode
*/
tANI_U8 isDisassocDeauthInProgress;
bool sta_deletion_in_progress;
+ struct parsed_ies parsed_ies;
+#ifdef SAP_AUTH_OFFLOAD
+ tANI_U8 dpuIndex;
+ tANI_U8 bcastDpuIndex;
+ tANI_U8 bcastMgmtDpuIdx;
+ tANI_U8 ucMgmtSig;
+#endif
struct sDphHashNode *next;
diff --git a/drivers/staging/prima/CORE/MAC/src/include/parserApi.h b/drivers/staging/prima/CORE/MAC/src/include/parserApi.h
index 8ab00e014d6..fac5c071272 100644
--- a/drivers/staging/prima/CORE/MAC/src/include/parserApi.h
+++ b/drivers/staging/prima/CORE/MAC/src/include/parserApi.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014, 2016-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -149,6 +149,8 @@ typedef struct sSirProbeRespBeacon
tDot11fIEWiderBWChanSwitchAnn WiderBWChanSwitchAnn;
#endif
tDot11fIEOBSSScanParameters OBSSScanParameters;
+ tDot11fIEhs20vendor_ie hs20vendor_ie;
+
} tSirProbeRespBeacon, *tpSirProbeRespBeacon;
// probe Request structure
@@ -220,6 +222,7 @@ typedef struct sSirAssocReq
tDot11fIEVHTCaps VHTCaps;
tDot11fIEOperatingMode operMode;
#endif
+ tDot11fIEhs20vendor_ie hs20vendor_ie;
} tSirAssocReq, *tpSirAssocReq;
@@ -960,7 +963,6 @@ void PopulateDot11fAssocRspRates ( tpAniSirGlobal pMac, tDot11fIESuppRates *pSup
int FindIELocation( tpAniSirGlobal pMac,
tpSirRSNie pRsnIe,
tANI_U8 EID);
-#endif
#ifdef WLAN_FEATURE_11AC
tSirRetStatus
@@ -995,3 +997,21 @@ tSirRetStatus ValidateAndRectifyIEs(tpAniSirGlobal pMac,
tANI_U8 *pMgmtFrame,
tANI_U32 nFrameBytes,
tANI_U32 *nMissingRsnBytes);
+#ifdef SAP_AUTH_OFFLOAD
+void
+sap_auth_offload_update_rsn_ie(tpAniSirGlobal pmac,
+ tDot11fIERSNOpaque *pdot11f);
+#endif /* SAP_AUTH_OFFLOAD */
+
+/**
+ * sir_copy_hs20_ie() - Update HS 2.0 Information Element.
+ * @dest: dest HS IE buffer to be updated
+ * @src: src HS IE buffer
+ *
+ * Update HS2.0 IE info from src to dest
+ *
+ * Return: void
+ */
+void sir_copy_hs20_ie(tDot11fIEhs20vendor_ie *dest,
+ tDot11fIEhs20vendor_ie *src);
+#endif /* __PARSE_H__ */
diff --git a/drivers/staging/prima/CORE/MAC/src/include/sirParams.h b/drivers/staging/prima/CORE/MAC/src/include/sirParams.h
index 236d5282977..dca671d347e 100644
--- a/drivers/staging/prima/CORE/MAC/src/include/sirParams.h
+++ b/drivers/staging/prima/CORE/MAC/src/include/sirParams.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -144,8 +144,18 @@ typedef enum {
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
PER_BASED_ROAMING = 63,
#endif
+ SAP_MODE_WOW = 64,
+ /* SAP_OFFLOADS flag will be used for
+ * SAP auth offload, SAP DHCP offload and
+ * SAP DNS offload.
+ */
+ SAP_OFFLOADS = 65,
+ SAP_BUFF_ALLOC = 66,
+#ifdef WLAN_FEATURE_LFR_MBB
+ MAKE_BEFORE_BREAK = 67,
+#endif
NUD_DEBUG = 68,
- /*69 reserved for FATAL_EVENT_LOGGING */
+ FATAL_EVENT_LOGGING = 69,
/*70 reserved for WIFI_DUAL_BAND_ENABLE */
PROBE_RSP_TEMPLATE_VER1 = 71,
//MAX_FEATURE_SUPPORTED = 128
@@ -171,6 +181,11 @@ typedef enum eSriLinkState {
eSIR_LINK_FINISH_CAL_STATE = 13,
eSIR_LINK_LISTEN_STATE = 14,
eSIR_LINK_SEND_ACTION_STATE = 15,
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ eSIR_LINK_PRE_AUTH_REASSOC_STATE = 17,
+#endif
+
} tSirLinkState;
@@ -769,12 +784,33 @@ typedef struct sSirMbMsgP2p
#define SIR_HAL_PER_ROAM_SCAN_TRIGGER_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 289)
#endif
#define SIR_HAL_UPDATE_CFG_INT_PARAM (SIR_HAL_ITC_MSG_TYPES_BEGIN + 290)
+
+#ifdef SAP_AUTH_OFFLOAD
+#define SIR_HAL_SET_SAP_AUTH_OFL (SIR_HAL_ITC_MSG_TYPES_BEGIN + 291)
+#define SIR_HAL_SAP_OFL_ADD_STA (SIR_HAL_ITC_MSG_TYPES_BEGIN + 292)
+#define SIR_HAL_SAP_OFL_DEL_STA (SIR_HAL_ITC_MSG_TYPES_BEGIN + 293)
+#endif
+#ifdef DHCP_SERVER_OFFLOAD
+#define SIR_HAL_SET_DHCP_SERVER_OFFLOAD_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 294)
+#endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+#define SIR_HAL_SET_MDNS_OFFLOAD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 295)
+#define SIR_HAL_SET_MDNS_FQDN (SIR_HAL_ITC_MSG_TYPES_BEGIN + 296)
+#define SIR_HAL_SET_MDNS_RESPONSE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 297)
+#define SIR_HAL_GET_MDNS_STATUS (SIR_HAL_ITC_MSG_TYPES_BEGIN + 298)
+#endif /* MDNS_OFFLOAD */
+#ifdef WLAN_FEATURE_APFIND
+#define SIR_HAL_APFIND_SET_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 299)
+#define SIR_HAL_AP_FIND_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 300)
+#endif/* WLAN_FEATURE_APFIND */
+
+#define SIR_HAL_CAP_TSF_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 301)
+#define SIR_HAL_GET_TSF_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 302)
+
/* ARP Debug stats */
-#define SIR_HAL_SET_ARP_STATS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 301)
-#define SIR_HAL_GET_ARP_STATS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 302)
+#define SIR_HAL_SET_ARP_STATS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 303)
+#define SIR_HAL_GET_ARP_STATS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 304)
-#define SIR_HAL_TRIGGER_ADD_BA_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 303)
-#define SIR_HAL_GET_CON_STATUS (SIR_HAL_ITC_MSG_TYPES_BEGIN + 304)
#define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
// CFG message types
@@ -870,6 +906,11 @@ typedef struct sSirMbMsgP2p
#define SIR_LIM_DEAUTH_ACK_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x27)
#define SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x28)
+#ifdef WLAN_FEATURE_LFR_MBB
+#define SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x29)
+#define SIR_LIM_REASSOC_MBB_RSP_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x2A)
+#endif
+
#define SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE (SIR_LIM_TIMEOUT_MSG_START + 0x2C)
#define SIR_LIM_AUTH_RETRY_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x2D)
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/include/limApi.h b/drivers/staging/prima/CORE/MAC/src/pe/include/limApi.h
index 5b869d3f064..88bca93e8de 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/include/limApi.h
+++ b/drivers/staging/prima/CORE/MAC/src/pe/include/limApi.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2013, 2016 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -191,6 +191,9 @@ tSirRetStatus limUpdateGlobalChannelBonding(tpAniSirGlobal pMac, tHalBitVal cbBi
void limHandleLowRssiInd(tpAniSirGlobal pMac);
void limHandleBmpsStatusInd(tpAniSirGlobal pMac);
+#ifdef WLAN_FEATURE_APFIND
+void limHandleAPFindInd(tpAniSirGlobal pMac);
+#endif
void limHandleMissedBeaconInd(tpAniSirGlobal pMac, tpSirMsgQ pMsg);
tMgmtFrmDropReason limIsPktCandidateForDrop(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tANI_U32 subType);
boolean limIsDeauthDiassocForDrop(tpAniSirGlobal pMac,
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/include/limFT.h b/drivers/staging/prima/CORE/MAC/src/pe/include/limFT.h
index d7508495b6c..bf4dd64b408 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/include/limFT.h
+++ b/drivers/staging/prima/CORE/MAC/src/pe/include/limFT.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -52,6 +52,7 @@ extern void limFTInit(tpAniSirGlobal pMac);
extern int limProcessFTPreAuthReq(tpAniSirGlobal pMac, tpSirMsgQ pMsg);
extern void limPerformFTPreAuth(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data,
tpPESession psessionEntry);
+void limFTSetupAuthSession(tpAniSirGlobal pMac, tpPESession psessionEntry);
void limPerformPostFTPreAuth(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data,
tpPESession psessionEntry);
void limFTResumeLinkCb(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data);
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/include/limFTDefs.h b/drivers/staging/prima/CORE/MAC/src/pe/include/limFTDefs.h
index 97625a33021..9e856594c59 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/include/limFTDefs.h
+++ b/drivers/staging/prima/CORE/MAC/src/pe/include/limFTDefs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -57,6 +57,7 @@ typedef struct sSirFTPreAuthReq
{
tANI_U16 messageType; // eWNI_SME_FT_PRE_AUTH_REQ
tANI_U16 length;
+ tANI_U32 dot11mode;
tANI_BOOLEAN bPreAuthRspProcessed; /* Track if response is processed for this request
We expect only one response per request. */
tANI_U8 preAuthchannelNum;
@@ -81,6 +82,10 @@ typedef struct sSirFTPreAuthRsp
tANI_U8 ft_ies[MAX_FTIE_SIZE];
tANI_U16 ric_ies_length;
tANI_U8 ric_ies[MAX_FTIE_SIZE];
+#ifdef WLAN_FEATURE_LFR_MBB
+ enum sir_roam_cleanup_type reason;
+ tCsrRoamInfo *roam_info;
+#endif
} tSirFTPreAuthRsp, *tpSirFTPreAuthRsp;
/*--------------------------------------------------------------------------
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/include/limSession.h b/drivers/staging/prima/CORE/MAC/src/pe/include/limSession.h
index 7c049afc77c..21b75bfb4ba 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/include/limSession.h
+++ b/drivers/staging/prima/CORE/MAC/src/pe/include/limSession.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -353,6 +353,8 @@ typedef struct sPESession // Added to Support BT-AMP
tANI_BOOLEAN isCiscoVendorAP;
/* To hold OBSS Scan IE Parameters */
tSirOBSSHT40Param obssHT40ScanParam;
+ /* HS 2.0 Indication */
+ tDot11fIEhs20vendor_ie hs20vendor_ie;
/* flag to indicate country code in beacon */
tANI_U8 countryInfoPresent;
/* DSCP to UP mapping for HS 2.0 */
@@ -361,6 +363,12 @@ typedef struct sPESession // Added to Support BT-AMP
tANI_BOOLEAN is11Gonly;
tANI_BOOLEAN addBssfailed;
tDot11fIEExtCap ExtCap;
+ uint32_t sta_auth_retries_for_code17;
+ tDot11fIEHTCaps ht_caps;
+ tDot11fIEVHTCaps vht_caps;
+ tDot11fIEHTInfo ht_operation;
+ tDot11fIEVHTOperation vht_operation;
+ bool force_24ghz_in_ht20;
}tPESession, *tpPESession;
#define LIM_MAX_ACTIVE_SESSIONS 4
@@ -421,6 +429,7 @@ tpPESession peFindSessionByBssid(tpAniSirGlobal pMac, tANI_U8* bssid, tANI_
tpPESession peFindSessionByBssIdx(tpAniSirGlobal pMac, tANI_U8 bssIdx);
+tANI_S8 limGetInfraSessionId(tpAniSirGlobal pMac);
/*--------------------------------------------------------------------------
@@ -495,10 +504,5 @@ void peDeleteSession(tpAniSirGlobal pMac, tpPESession psessionEntry);
\sa
--------------------------------------------------------------------------*/
-
+int peFindBssIdxFromSmeSessionId(tpAniSirGlobal pMac, tANI_U8 sme_sessionId);
#endif //#if !defined( __LIM_SESSION_H )
-
-
-
-
-
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/include/lim_mbb.h b/drivers/staging/prima/CORE/MAC/src/pe/include/lim_mbb.h
new file mode 100644
index 00000000000..770263ef1e0
--- /dev/null
+++ b/drivers/staging/prima/CORE/MAC/src/pe/include/lim_mbb.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+void lim_process_preauth_mbb_rsp_timeout(tpAniSirGlobal mac);
+void lim_process_pre_auth_reassoc_req(tpAniSirGlobal mac, tpSirMsgQ msg);
+void lim_handle_pre_auth_mbb_rsp(tpAniSirGlobal mac,
+ tSirRetStatus status, tpPESession session_entry);
+void lim_process_reassoc_mbb_rsp_timeout(tpAniSirGlobal mac);
+void lim_handle_reassoc_mbb_fail(tpAniSirGlobal mac,
+ tpPESession session_entry);
+void lim_handle_reassoc_mbb_success(tpAniSirGlobal mac,
+ tpPESession session_entry, tpSirAssocRsp assoc_rsp, tpDphHashNode sta_ds);
+void lim_process_sta_mlm_del_sta_rsp_mbb(tpAniSirGlobal mac,
+ tpSirMsgQ lim_msg, tpPESession session_entry);
+void lim_process_sta_mlm_del_bss_rsp_mbb(tpAniSirGlobal mac,
+ tpSirMsgQ lim_msg, tpPESession session_entry);
+void lim_process_sta_mlm_add_bss_rsp_mbb(tpAniSirGlobal mac,
+ tpSirMsgQ limMsgQ,tpPESession session_entry);
+void lim_process_sta_mlm_add_sta_rsp_mbb(tpAniSirGlobal mac,
+ tpSirMsgQ limMsgQ,tpPESession session_entry);
+eAniBoolean lim_is_mbb_reassoc_in_progress(tpAniSirGlobal mac,
+ tpPESession session_entry);
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limApi.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limApi.c
index f49aa01580f..b21ad3aeef5 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limApi.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limApi.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -703,6 +703,18 @@ tSirRetStatus limStart(tpAniSirGlobal pMac)
return retCode;
}
+static void
+limInitAssocRspCompletiontionList(tpAniSirGlobal pMac)
+{
+ vos_list_init(&pMac->assoc_rsp_completion_list);
+}
+
+static void
+limDestroyAssocRspCompletiontionList(tpAniSirGlobal pMac)
+{
+ vos_list_destroy(&pMac->assoc_rsp_completion_list);
+}
+
/**
* limInitialize()
*
@@ -753,6 +765,7 @@ limInitialize(tpAniSirGlobal pMac)
// Initializations for maintaining peers in IBSS
limIbssInit(pMac);
+ limInitAssocRspCompletiontionList(pMac);
pmmInitialize(pMac);
@@ -946,7 +959,7 @@ limCleanup(tpAniSirGlobal pMac)
vos_mem_free(pMac->lim.gpLimMlmScanReq);
pMac->lim.gpLimMlmScanReq = NULL;
}
-
+ limDestroyAssocRspCompletiontionList(pMac);
#if 0
if(NULL != pMac->lim.beacon)
{
@@ -2160,6 +2173,21 @@ void limHandleBmpsStatusInd(tpAniSirGlobal pMac)
return;
}
+#ifdef WLAN_FEATURE_APFIND
+void limHandleAPFindInd(tpAniSirGlobal pMac)
+{
+ tANI_S8 pe_sessionid = -1;
+ /* Find STA connection session */
+ pe_sessionid = limGetInfraSessionId(pMac);
+ if (pe_sessionid != -1)
+ limTearDownLinkWithAp(pMac,
+ pe_sessionid,
+ eSIR_BEACON_MISSED);
+ else
+ limLog(pMac, LOGE,
+ FL("session id doesn't exist for infra"));
+}
+#endif
/** -----------------------------------------------------------------
\brief limHandleMissedBeaconInd() - handles missed beacon indication
@@ -2682,3 +2710,151 @@ eHalStatus pe_ReleaseGlobalLock( tAniSirLim *psPe)
}
return (status);
}
+/**
+ * lim_process_sme_cap_tsf_req()- send cap tsf request to WDA
+ * Get bss_idx from PE and fill in cap tsf request.
+ * @pMac:Mac ctx
+ * @pMsgBuf: message buffer from sme
+ * Returns success on post to WDA, otherwise failure
+ */
+
+tSirRetStatus lim_process_sme_cap_tsf_req(tpAniSirGlobal pMac,
+ tANI_U32 *pMsgBuf)
+{
+ tSirCapTsfParams *pMsg = NULL;
+ tpPESession psessionEntry = NULL;
+ uint8_t sessionId;
+ tSirMsgQ msg;
+ tSirCapTsfParams *cap_tsf_params;
+
+ pMsg = (tSirCapTsfParams*)pMsgBuf;
+ if (pMsg == NULL) {
+ limLog(pMac, LOGE, FL("NULL pMsg"));
+ return eSIR_FAILURE;
+ }
+
+ psessionEntry = peFindSessionByBssid(pMac, pMsg->bssid, &sessionId);
+ if (NULL == psessionEntry)
+ {
+ limLog(pMac, LOGE, FL("NULL psessionEntry"));
+ return eSIR_FAILURE;
+ }
+ cap_tsf_params = (tSirCapTsfParams *)
+ vos_mem_malloc(sizeof(*cap_tsf_params));
+ if (!cap_tsf_params) {
+ limLog(pMac, LOGE, FL(" Unable to allocate memory for cap tsf params"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ vos_mem_copy (cap_tsf_params, pMsg, sizeof(*cap_tsf_params));
+ cap_tsf_params->bss_idx = psessionEntry->bssIdx;
+
+ msg.type = WDA_CAP_TSF_REQ;
+ msg.reserved = 0;
+ msg.bodyptr = cap_tsf_params;
+ msg.bodyval = 0;
+ if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg))
+ {
+ limLog(pMac, LOGE, FL("lim_process_sme_cap_tsf_req failed\n"));
+ vos_mem_free(cap_tsf_params);
+ return eSIR_FAILURE;
+ }
+
+ return eSIR_SUCCESS;
+}
+
+/**
+ * lim_process_sme_get_tsf_req()- send get tsf request to WDA
+ * Get bss_idx from PE and fill in cap tsf request.
+ * @pMac:Mac ctx
+ * @pMsgBuf: message buffer from sme
+ * Returns success on post to WDA, otherwise failure
+ */
+tSirRetStatus lim_process_sme_get_tsf_req(tpAniSirGlobal pMac,
+ tANI_U32 *pMsgBuf)
+{
+ tSirCapTsfParams *pMsg = NULL;
+ tpPESession psessionEntry = NULL;
+ uint8_t sessionId;
+ tSirMsgQ msg;
+ tSirCapTsfParams *get_tsf_params;
+
+ pMsg = (tSirCapTsfParams*)pMsgBuf;
+ if (pMsg == NULL) {
+ limLog(pMac, LOGE, FL("NULL pMsg"));
+ return eSIR_FAILURE;
+ }
+
+ psessionEntry = peFindSessionByBssid(pMac, pMsg->bssid, &sessionId);
+ if (NULL == psessionEntry)
+ {
+ limLog(pMac, LOGE, FL("NULL psessionEntry"));
+ return eSIR_FAILURE;
+ }
+ get_tsf_params = (tSirCapTsfParams *)
+ vos_mem_malloc(sizeof(*get_tsf_params));
+ if (!get_tsf_params) {
+ limLog(pMac, LOGE, FL(" Unable to allocate memory for cap tsf params"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ vos_mem_copy (get_tsf_params, pMsg, sizeof(*get_tsf_params));
+ get_tsf_params->bss_idx = psessionEntry->bssIdx;
+
+ msg.type = WDA_GET_TSF_REQ;
+ msg.reserved = 0;
+ msg.bodyptr = get_tsf_params;
+ msg.bodyval = 0;
+ if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg))
+ {
+ limLog(pMac, LOGE, FL("lim_process_sme_cap_tsf_req failed\n"));
+ vos_mem_free(get_tsf_params);
+ return eSIR_FAILURE;
+ }
+
+ return eSIR_SUCCESS;
+}
+
+/**
+ * lim_process_sme_del_ba_ses_req()- process del ba req
+ * @pMac:Mac ctx
+ * @pMsgBuf: message buffer from sme
+ * Returns success on taking action based on cfg value, otherwise failure
+ */
+tSirRetStatus lim_process_sme_del_ba_ses_req(tpAniSirGlobal pMac,
+ tANI_U32 *pMsgBuf)
+{
+ tDelBaParams *pMsg = NULL;
+ tpPESession psessionEntry = NULL;
+ int val;
+
+ pMsg = (tDelBaParams*)pMsgBuf;
+ if (pMsg == NULL) {
+ limLog(pMac, LOGE, FL("NULL pMsg"));
+ return eSIR_FAILURE;
+ }
+
+ psessionEntry = peFindSessionBySessionId(pMac, pMsg->session_id);
+ if (NULL == psessionEntry)
+ {
+ limLog(pMac, LOGE, FL("NULL psessionEntry"));
+ return eSIR_FAILURE;
+ }
+
+ if (wlan_cfgGetInt
+ (pMac, WNI_CFG_ENABLE_TX_RX_AGGREGATION, &val) !=
+ eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGE,
+ FL( "Unable to get WNI_CFG_ENABLE_TX_RX_AGGREGATION"));
+ return eSIR_FAILURE;
+ }
+
+ if (!val)
+ {
+ limLog(pMac, LOGW,
+ FL("user requested to disable all RX BA sessions"));
+ limDeleteBASessions(pMac, psessionEntry, BA_BOTH_DIRECTIONS,
+ eSIR_MAC_PEER_TIMEDOUT_REASON);
+ }
+
+ return eSIR_SUCCESS;
+}
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limAssocUtils.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limAssocUtils.c
index 188f2e57868..ed44ecea424 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limAssocUtils.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limAssocUtils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -1011,6 +1011,8 @@ limRejectAssociation(tpAniSirGlobal pMac, tSirMacAddr peerAddr, tANI_U8 subType,
tANI_U16 staId, tANI_U8 deleteSta, tSirResultCodes rCode, tpPESession psessionEntry )
{
tpDphHashNode pStaDs;
+ assoc_rsp_tx_context *tx_complete_context = NULL;
+ vos_list_node_t *pNode= NULL;
limLog(pMac, LOG1, FL("Sessionid: %d authType: %d subType: %d "
"addPreAuthContext: %d staId: %d deleteSta: %d rCode : %d "
@@ -1049,23 +1051,38 @@ limRejectAssociation(tpAniSirGlobal pMac, tSirMacAddr peerAddr, tANI_U8 subType,
return;
}
+ vos_list_peek_front(&pMac->assoc_rsp_completion_list, &pNode);
+
+ tx_complete_context = vos_mem_malloc(sizeof(*tx_complete_context));
+ if (!tx_complete_context)
+ {
+ limLog(pMac, LOGW,
+ FL("Failed to allocate memory"));
+
+ return;
+ }
+ tx_complete_context->psessionID = psessionEntry->peSessionId;
+ tx_complete_context->staId = staId;
+
+ if (pNode)
+ vos_list_insert_back(&pMac->assoc_rsp_completion_list,
+ &tx_complete_context->node);
+ else
+ vos_list_insert_front(&pMac->assoc_rsp_completion_list,
+ &tx_complete_context->node);
/**
* Polaris has state for this STA.
* Trigger cleanup.
*/
pStaDs->mlmStaContext.cleanupTrigger = eLIM_REASSOC_REJECT;
-
- // Receive path cleanup
- limCleanupRxPath(pMac, pStaDs, psessionEntry);
-
// Send Re/Association Response with
// status code to requesting STA.
limSendAssocRspMgmtFrame(pMac,
rCode,
0,
peerAddr,
- subType, 0,psessionEntry);
+ subType, 0,psessionEntry, tx_complete_context);
if ( psessionEntry->parsedAssocReq[pStaDs->assocId] != NULL)
{
@@ -1085,7 +1102,7 @@ limRejectAssociation(tpAniSirGlobal pMac, tSirMacAddr peerAddr, tANI_U8 subType,
eSIR_MAC_MAX_ASSOC_STA_REACHED_STATUS,
1,
peerAddr,
- subType, 0,psessionEntry);
+ subType, 0,psessionEntry, NULL);
// Log error
limLog(pMac, LOGW,
FL("received Re/Assoc req when max associated STAs reached from "));
@@ -2421,7 +2438,15 @@ limAddSta(
}
else
#endif
- pAddStaParams->staIdx = HAL_STA_INVALID_IDX;
+#ifdef SAP_AUTH_OFFLOAD
+ if (!pMac->sap_auth_offload)
+ pAddStaParams->staIdx = HAL_STA_INVALID_IDX;
+ else
+ pAddStaParams->staIdx = pStaDs->staIndex;
+#else
+ pAddStaParams->staIdx = HAL_STA_INVALID_IDX;
+#endif
+
pAddStaParams->staType = pStaDs->staType;
pAddStaParams->updateSta = updateEntry;
@@ -2593,11 +2618,30 @@ limAddSta(
"p2pCapableSta: %d"), pAddStaParams->htLdpcCapable,
pAddStaParams->vhtLdpcCapable, pAddStaParams->p2pCapableSta);
+#ifdef SAP_AUTH_OFFLOAD
+ if (pMac->sap_auth_offload) {
+ pAddStaParams->dpuIndex = pStaDs->dpuIndex;
+ pAddStaParams->bcastDpuIndex = pStaDs->bcastDpuIndex;
+ pAddStaParams->bcastMgmtDpuIdx = pStaDs->bcastMgmtDpuIdx;
+ pAddStaParams->ucUcastSig = pStaDs->ucUcastSig;
+ pAddStaParams->ucBcastSig = pStaDs->ucBcastSig;
+ pAddStaParams->ucMgmtSig = pStaDs->ucMgmtSig;
+ pAddStaParams->bssIdx = pStaDs->bssId;
+ }
+#endif
+
//we need to defer the message until we get the response back from HAL.
if (pAddStaParams->respReqd)
SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
- msgQ.type = WDA_ADD_STA_REQ;
+#ifdef SAP_AUTH_OFFLOAD
+ if (pMac->sap_auth_offload && LIM_IS_AP_ROLE(psessionEntry))
+ msgQ.type = WDA_SAP_OFL_ADD_STA;
+ else
+ msgQ.type = WDA_ADD_STA_REQ;
+#else
+ msgQ.type = WDA_ADD_STA_REQ;
+#endif
msgQ.reserved = 0;
msgQ.bodyptr = pAddStaParams;
@@ -2723,7 +2767,14 @@ limDelSta(
pDelStaParams->sessionId = psessionEntry->peSessionId;
pDelStaParams->status = eHAL_STATUS_SUCCESS;
+#ifdef SAP_AUTH_OFFLOAD
+ if (pMac->sap_auth_offload && LIM_IS_AP_ROLE(psessionEntry))
+ msgQ.type = WDA_SAP_OFL_DEL_STA;
+ else
+ msgQ.type = WDA_DELETE_STA_REQ;
+#else
msgQ.type = WDA_DELETE_STA_REQ;
+#endif
msgQ.reserved = 0;
msgQ.bodyptr = pDelStaParams;
msgQ.bodyval = 0;
@@ -3374,6 +3425,9 @@ limCheckAndAnnounceJoinSuccess(tpAniSirGlobal pMac,
mlmJoinCnf.sessionId = psessionEntry->peSessionId;
limPostSmeMessage(pMac, LIM_MLM_JOIN_CNF, (tANI_U32 *) &mlmJoinCnf);
} // if ((pMac->lim.gLimSystemRole == IBSS....
+
+ /* Update HS 2.0 Information Element */
+ sir_copy_hs20_ie(&psessionEntry->hs20vendor_ie, &pBPR->hs20vendor_ie);
}
/**
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limAssocUtils.h b/drivers/staging/prima/CORE/MAC/src/pe/lim/limAssocUtils.h
index d44afc5abeb..8b4705a8dda 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limAssocUtils.h
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limAssocUtils.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014, 2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -188,6 +188,7 @@ void limSendSmeTsmIEInd( tpAniSirGlobal pMac, tpPESession psessionEntry,
tANI_U8 tid, tANI_U8 state, tANI_U16 measInterval);
#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
+tANI_U16 __limGetSmeJoinReqSizeForAlloc(tANI_U8 *pBuf);
#endif /* __LIM_ASSOC_UTILS_H */
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limFT.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limFT.c
index 7a60cac737e..ba78826ae70 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limFT.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limFT.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -705,7 +705,6 @@ tpPESession limFillFTSession(tpAniSirGlobal pMac,
tPowerdBm localPowerConstraint;
tPowerdBm regMax;
tSchBeaconStruct *pBeaconStruct;
- uint32 selfDot11Mode;
ePhyChanBondState cbMode;
pBeaconStruct = vos_mem_malloc(sizeof(tSchBeaconStruct));
@@ -750,9 +749,8 @@ tpPESession limFillFTSession(tpAniSirGlobal pMac,
vos_mem_copy(pftSessionEntry->ssId.ssId, pBeaconStruct->ssId.ssId,
pftSessionEntry->ssId.length);
- wlan_cfgGetInt(pMac, WNI_CFG_DOT11_MODE, &selfDot11Mode);
- limLog(pMac, LOG1, FL("selfDot11Mode %d"),selfDot11Mode );
- pftSessionEntry->dot11mode = selfDot11Mode;
+ pftSessionEntry->dot11mode = pMac->ft.ftPEContext.pFTPreAuthReq->dot11mode;
+ limLog(pMac, LOG1, FL("dot11mode %d"), pftSessionEntry->dot11mode);
pftSessionEntry->vhtCapability =
(IS_DOT11_MODE_VHT(pftSessionEntry->dot11mode)
&& IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps));
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c
index 36b7a68a8b1..d60902a0e9d 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -55,6 +55,9 @@
#endif //FEATURE_WLAN_DIAG_SUPPORT
#include "limSession.h"
#include "limSerDesUtils.h"
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "lim_mbb.h"
+#endif
/**
@@ -111,6 +114,15 @@ limDeleteStaContext(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
return;
}
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (lim_is_mbb_reassoc_in_progress(pMac, psessionEntry))
+ {
+ limLog(pMac, LOGE,
+ FL("Ignore delete sta as LFR MBB in progress"));
+ return;
+ }
+#endif
+
switch(pMsg->reasonCode)
{
case HAL_DEL_STA_REASON_CODE_KEEP_ALIVE:
@@ -474,6 +486,15 @@ void limHandleHeartBeatFailure(tpAniSirGlobal pMac,tpPESession psessionEntry)
/* Ensure HB Status for the session has been reseted */
psessionEntry->LimHBFailureStatus = eANI_BOOLEAN_FALSE;
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (lim_is_mbb_reassoc_in_progress(pMac, psessionEntry))
+ {
+ limLog(pMac, LOGE,
+ FL("Ignore Heartbeat failure as LFR MBB in progress"));
+ return;
+ }
+#endif
+
if (((psessionEntry->limSystemRole == eLIM_STA_ROLE)||
(psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE))&&
(psessionEntry->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE)&&
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessActionFrame.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessActionFrame.c
index 5d6ebecea5b..387e32eac8e 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessActionFrame.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessActionFrame.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -68,6 +68,10 @@
#endif
#include "wlan_qct_wda.h"
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "lim_mbb.h"
+#endif
+
#define BA_DEFAULT_TX_BUFFER_SIZE 64
@@ -176,7 +180,16 @@ void limStopTxAndSwitchChannel(tpAniSirGlobal pMac, tANI_U8 sessionId)
tSirRetStatus limStartChannelSwitch(tpAniSirGlobal pMac, tpPESession psessionEntry)
{
limLog(pMac, LOG1, FL(" ENTER"));
-
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (lim_is_mbb_reassoc_in_progress(pMac, psessionEntry))
+ {
+ limLog(pMac, LOGE,
+ FL("Ignore channel switch as LFR MBB in progress"));
+ return eSIR_SUCCESS;
+ }
+#endif
+
/*If channel switch is already running and it is on a different session, just return*/
/*This need to be removed for MCC */
if( limIsChanSwitchRunning (pMac) &&
@@ -923,7 +936,8 @@ __limProcessQosMapConfigureFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,
return;
}
limSendSmeMgmtFrameInd(pMac, psessionEntry->smeSessionId,
- pRxPacketInfo, psessionEntry, 0);
+ pRxPacketInfo, psessionEntry,
+ WDA_GET_RX_RSSI_DB(pRxPacketInfo));
}
#ifdef ANI_SUPPORT_11H
@@ -1225,10 +1239,10 @@ __limValidateDelBAParameterSet( tpAniSirGlobal pMac,
tDot11fFfDelBAParameterSet baParameterSet,
tpDphHashNode pSta )
{
- tSirMacStatusCodes statusCode = eSIR_MAC_STA_BLK_ACK_NOT_SUPPORTED_STATUS;
+tSirMacStatusCodes statusCode = eSIR_MAC_STA_BLK_ACK_NOT_SUPPORTED_STATUS;
- if (!(baParameterSet.tid < STACFG_MAX_TC))
- return statusCode;
+ if (!(baParameterSet.tid < STACFG_MAX_TC))
+ return statusCode;
// Validate if a BA is active for the requested TID
if( pSta->tcCfg[baParameterSet.tid].fUseBATx ||
@@ -1267,7 +1281,7 @@ __limProcessAddBAReq( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession ps
tpDphHashNode pSta;
tSirMacStatusCodes status = eSIR_MAC_SUCCESS_STATUS;
tANI_U16 aid;
- tANI_U32 frameLen, nStatus,val;
+ tANI_U32 frameLen, nStatus,val, val1;
tANI_U8 *pBody;
tANI_U8 delBAFlag =0;
@@ -1275,6 +1289,7 @@ __limProcessAddBAReq( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession ps
pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo );
frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo );
val = 0;
+ val1 = 0;
// Unpack the received frame
nStatus = dot11fUnpackAddBAReq( pMac, pBody, frameLen, &frmAddBAReq );
@@ -1336,6 +1351,20 @@ __limProcessAddBAReq( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession ps
}
#endif //WLAN_SOFTAP_VSTA_FEATURE
+ if (wlan_cfgGetInt(pMac, WNI_CFG_ENABLE_TX_RX_AGGREGATION, &val1) !=
+ eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGE,
+ FL("Unable to get WNI_CFG_ENABLE_TX_RX_AGGREGATION"));
+ val1 = 1;
+ }
+ if (!val1)
+ {
+ limLog(pMac, LOGE,
+ FL("aggregation disabled - ignoring ADDBA"));
+ goto returnAfterError;
+ }
+
if (wlan_cfgGetInt(pMac, WNI_CFG_DEL_ALL_RX_TX_BA_SESSIONS_2_4_G_BTC, &val) !=
eSIR_SUCCESS)
{
@@ -2154,7 +2183,8 @@ static void __limProcessSAQueryResponseActionFrame(tpAniSirGlobal pMac, tANI_U8
if (eLIM_STA_ROLE == psessionEntry->limSystemRole)
{
limSendSmeMgmtFrameInd(pMac, psessionEntry->smeSessionId,
- pRxPacketInfo, psessionEntry, 0);
+ pRxPacketInfo, psessionEntry,
+ WDA_GET_RX_RSSI_DB(pRxPacketInfo));
return;
}
@@ -2592,7 +2622,8 @@ limProcessActionFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession ps
// type is ACTION
limSendSmeMgmtFrameInd(pMac, psessionEntry->smeSessionId,
pRxPacketInfo,
- psessionEntry, 0);
+ psessionEntry,
+ WDA_GET_RX_RSSI_DB(pRxPacketInfo));
}
else
{
@@ -2727,7 +2758,8 @@ limProcessActionFrameNoSession(tpAniSirGlobal pMac, tANI_U8 *pBd)
{
/* Forward to the SME to HDD to wpa_supplicant */
// type is ACTION
- limSendSmeMgmtFrameInd(pMac, 0, pBd, NULL, 0);
+ limSendSmeMgmtFrameInd(pMac, 0, pBd, NULL,
+ WDA_GET_RX_RSSI_DB(pBd));
}
else
{
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessAssocReqFrame.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessAssocReqFrame.c
index 2e7e5de6838..e1b7978999c 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessAssocReqFrame.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessAssocReqFrame.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -260,7 +260,7 @@ limProcessAssocReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,
limSendAssocRspMgmtFrame( pMac, eSIR_SUCCESS,
pStaDs->assocId, pStaDs->staAddr,
pStaDs->mlmStaContext.subType, pStaDs,
- psessionEntry);
+ psessionEntry, NULL);
limLog(pMac, LOGE,
FL("DUT already received an assoc request frame "
"and STA is sending another assoc req.So, do not "
@@ -300,7 +300,7 @@ limProcessAssocReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,
eSIR_MAC_UNSPEC_FAILURE_STATUS,
1,
pHdr->sa,
- subType, 0,psessionEntry);
+ subType, 0,psessionEntry, NULL);
return ;
}
@@ -312,7 +312,7 @@ limProcessAssocReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,
eSIR_MAC_MIC_FAILURE_REASON,
1,
pHdr->sa,
- subType, 0, psessionEntry);
+ subType, 0, psessionEntry, NULL);
return;
}
@@ -336,7 +336,8 @@ limProcessAssocReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,
limLog(pMac, LOGW,
FL("Parse error AssocRequest, length=%d from "MAC_ADDRESS_STR),
framelen, MAC_ADDR_ARRAY(pHdr->sa));
- limSendAssocRspMgmtFrame(pMac, eSIR_MAC_UNSPEC_FAILURE_STATUS, 1, pHdr->sa, subType, 0, psessionEntry);
+ limSendAssocRspMgmtFrame(pMac, eSIR_MAC_UNSPEC_FAILURE_STATUS, 1,
+ pHdr->sa, subType, 0, psessionEntry, NULL);
goto error;
}
@@ -378,7 +379,7 @@ limProcessAssocReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,
eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
1,
pHdr->sa,
- subType, 0,psessionEntry);
+ subType, 0,psessionEntry ,NULL);
goto error;
}
@@ -403,7 +404,7 @@ limProcessAssocReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,
eSIR_MAC_UNSPEC_FAILURE_STATUS,
1,
pHdr->sa,
- subType, 0,psessionEntry);
+ subType, 0,psessionEntry, NULL);
goto error;
}
@@ -442,7 +443,7 @@ limProcessAssocReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,
eSIR_MAC_BASIC_RATES_NOT_SUPPORTED_STATUS,
1,
pHdr->sa,
- subType, 0,psessionEntry);
+ subType, 0,psessionEntry, NULL);
goto error;
}
@@ -455,7 +456,7 @@ limProcessAssocReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,
limLog(pMac, LOGE, FL("SOFTAP was in 11G only mode, rejecting legacy "
"STA : "MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pHdr->sa));
limSendAssocRspMgmtFrame( pMac, eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
- 1, pHdr->sa, subType, 0, psessionEntry );
+ 1, pHdr->sa, subType, 0, psessionEntry, NULL);
goto error;
}//end if phyMode == 11G_only
@@ -467,7 +468,7 @@ limProcessAssocReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,
limLog(pMac, LOGE, FL("SOFTAP was in 11N only mode, rejecting legacy "
"STA : "MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pHdr->sa));
limSendAssocRspMgmtFrame( pMac, eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
- 1, pHdr->sa, subType, 0, psessionEntry );
+ 1, pHdr->sa, subType, 0, psessionEntry, NULL);
goto error;
}//end if PhyMode == 11N_only
@@ -554,7 +555,7 @@ limProcessAssocReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,
eSIR_MAC_OUTSIDE_SCOPE_OF_SPEC_STATUS,
1,
pHdr->sa,
- subType, 0,psessionEntry);
+ subType, 0,psessionEntry, NULL);
goto error;
}
@@ -584,7 +585,7 @@ limProcessAssocReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,
eSIR_MAC_BASIC_RATES_NOT_SUPPORTED_STATUS,
1,
pHdr->sa,
- subType, 0,psessionEntry);
+ subType, 0,psessionEntry, NULL);
#ifdef WLAN_DEBUG
@@ -621,7 +622,7 @@ limProcessAssocReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,
eSIR_MAC_WME_REFUSED_STATUS,
1,
pHdr->sa,
- subType, 0,psessionEntry);
+ subType, 0,psessionEntry, NULL);
goto error;
}
@@ -710,7 +711,7 @@ limProcessAssocReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,
FL("Invalid RSNIE received"));
limSendAssocRspMgmtFrame(pMac,
eSIR_MAC_INVALID_RSN_IE_CAPABILITIES_STATUS,
- 1, pHdr->sa, subType, 0,psessionEntry);
+ 1, pHdr->sa, subType, 0,psessionEntry, NULL);
goto error;
}
@@ -732,7 +733,7 @@ limProcessAssocReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,
status,
1,
pHdr->sa,
- subType, 0,psessionEntry);
+ subType, 0,psessionEntry, NULL);
goto error;
@@ -751,7 +752,7 @@ limProcessAssocReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,
eSIR_MAC_UNSUPPORTED_RSN_IE_VERSION_STATUS,
1,
pHdr->sa,
- subType, 0,psessionEntry);
+ subType, 0,psessionEntry, NULL);
goto error;
}
@@ -768,7 +769,7 @@ limProcessAssocReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,
eSIR_MAC_INVALID_INFORMATION_ELEMENT_STATUS,
1,
pHdr->sa,
- subType, 0,psessionEntry);
+ subType, 0,psessionEntry, NULL);
goto error;
@@ -787,7 +788,7 @@ limProcessAssocReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,
limLog(pMac, LOGE, FL("Invalid WPA IE"));
limSendAssocRspMgmtFrame(pMac,
eSIR_MAC_INVALID_INFORMATION_ELEMENT_STATUS,
- 1, pHdr->sa, subType, 0,psessionEntry);
+ 1, pHdr->sa, subType, 0,psessionEntry, NULL);
goto error;
}
/* check the groupwise and pairwise cipher suites */
@@ -803,7 +804,7 @@ limProcessAssocReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,
status,
1,
pHdr->sa,
- subType, 0,psessionEntry);
+ subType, 0,psessionEntry, NULL);
goto error;
}
@@ -820,7 +821,7 @@ limProcessAssocReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,
eSIR_MAC_INVALID_INFORMATION_ELEMENT_STATUS,
1,
pHdr->sa,
- subType, 0,psessionEntry);
+ subType, 0,psessionEntry, NULL);
goto error;
}/* end - if(pAssocReq->wpa.length) */
@@ -949,7 +950,8 @@ limProcessAssocReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,
*/
pStaDs->pmfSaQueryRetryCount = 0;
limSendAssocRspMgmtFrame(pMac, eSIR_MAC_TRY_AGAIN_LATER, 1,
- pHdr->sa, subType, pStaDs, psessionEntry);
+ pHdr->sa, subType, pStaDs,
+ psessionEntry, NULL);
limSendSaQueryRequestFrame(
pMac, (tANI_U8 *)&(pStaDs->pmfSaQueryCurrentTransId),
pHdr->sa, psessionEntry);
@@ -970,7 +972,8 @@ limProcessAssocReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,
// Request with try again later
case DPH_SA_QUERY_IN_PROGRESS:
limSendAssocRspMgmtFrame(pMac, eSIR_MAC_TRY_AGAIN_LATER, 1,
- pHdr->sa, subType, 0, psessionEntry);
+ pHdr->sa, subType, 0, psessionEntry,
+ NULL);
goto error;
// SA Query procedure timed out, accept Association Request
@@ -1046,7 +1049,7 @@ limProcessAssocReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,
eSIR_MAC_QAP_NO_BANDWIDTH_REASON,
1,
pHdr->sa,
- subType, 0,psessionEntry);
+ subType, 0,psessionEntry, NULL);
#ifdef WLAN_DEBUG
pMac->lim.gLimNumAssocReqDropACRejectTS++;
#endif
@@ -1062,7 +1065,7 @@ limProcessAssocReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,
eSIR_MAC_QAP_NO_BANDWIDTH_REASON,
1,
pHdr->sa,
- subType, 0,psessionEntry);
+ subType, 0,psessionEntry, NULL);
#ifdef WLAN_DEBUG
pMac->lim.gLimNumAssocReqDropACRejectSta++;
#endif
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c
index d08df5b6355..ccc8ec71041 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -56,6 +56,10 @@
#include "eseApi.h"
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "lim_mbb.h"
+#endif
+
extern tSirRetStatus schBeaconEdcaProcess(tpAniSirGlobal pMac, tSirMacEdcaParamSetIE *edca, tpPESession psessionEntry);
@@ -528,16 +532,18 @@ limProcessAssocRspFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tANI_U8 sub
psessionEntry->assocRsp = NULL;
}
- psessionEntry->assocRsp = vos_mem_malloc(frameLen);
- if (NULL == psessionEntry->assocRsp)
- {
- PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store assoc response, len = %d"), frameLen);)
- }
- else
- {
- //Store the Assoc response. This is sent to csr/hdd in join cnf response.
- vos_mem_copy(psessionEntry->assocRsp, pBody, frameLen);
- psessionEntry->assocRspLen = frameLen;
+ if (frameLen) {
+ psessionEntry->assocRsp = vos_mem_malloc(frameLen);
+ if (NULL == psessionEntry->assocRsp)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store assoc response, len = %d"), frameLen);)
+ }
+ else
+ {
+ //Store the Assoc response. This is sent to csr/hdd in join cnf response.
+ vos_mem_copy(psessionEntry->assocRsp, pBody, frameLen);
+ psessionEntry->assocRspLen = frameLen;
+ }
}
#ifdef WLAN_FEATURE_VOWIFI_11R
@@ -549,16 +555,19 @@ limProcessAssocRspFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tANI_U8 sub
if(pAssocRsp->ricPresent)
{
psessionEntry->RICDataLen = pAssocRsp->num_RICData * sizeof(tDot11fIERICDataDesc);
- psessionEntry->ricData = vos_mem_malloc(psessionEntry->RICDataLen);
- if ( NULL == psessionEntry->ricData )
- {
- PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store assoc response"));)
- psessionEntry->RICDataLen = 0;
- }
- else
+ if (psessionEntry->RICDataLen)
{
- vos_mem_copy(psessionEntry->ricData,
- &pAssocRsp->RICData[0], psessionEntry->RICDataLen);
+ psessionEntry->ricData = vos_mem_malloc(psessionEntry->RICDataLen);
+ if ( NULL == psessionEntry->ricData )
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store assoc response"));)
+ psessionEntry->RICDataLen = 0;
+ }
+ else
+ {
+ vos_mem_copy(psessionEntry->ricData,
+ &pAssocRsp->RICData[0], psessionEntry->RICDataLen);
+ }
}
}
else
@@ -636,6 +645,11 @@ limProcessAssocRspFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tANI_U8 sub
limDeactivateAndChangeTimer(pMac, eLIM_ASSOC_FAIL_TIMER);
else // Stop Reassociation failure timer
{
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb)
+ limDeactivateAndChangeTimer(pMac, eLIM_REASSOC_MBB_RSP_TIMER);
+#endif
+
#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
pMac->lim.reAssocRetryAttempt = 0;
if ((NULL != pMac->lim.pSessionEntry) && (NULL != pMac->lim.pSessionEntry->pLimMlmReassocRetryReq))
@@ -644,7 +658,10 @@ limProcessAssocRspFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tANI_U8 sub
pMac->lim.pSessionEntry->pLimMlmReassocRetryReq = NULL;
}
#endif
- limDeactivateAndChangeTimer(pMac, eLIM_REASSOC_FAIL_TIMER);
+
+ /* Dactivate timer when it is not LFR MBB */
+ if (!pMac->ft.ftSmeContext.is_preauth_lfr_mbb)
+ limDeactivateAndChangeTimer(pMac, eLIM_REASSOC_FAIL_TIMER);
}
if (pAssocRsp->statusCode != eSIR_MAC_SUCCESS_STATUS)
@@ -668,6 +685,9 @@ limProcessAssocRspFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tANI_U8 sub
}else
mlmAssocCnf.resultCode = eSIR_SME_ASSOC_REFUSED;
+ if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb)
+ goto assocReject;
+
// Delete Pre-auth context for the associated BSS
if (limSearchPreAuthList(pMac, pHdr->sa))
limDeletePreAuthNode(pMac, pHdr->sa);
@@ -696,18 +716,22 @@ limProcessAssocRspFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tANI_U8 sub
* assoc/reassoc response
* NOTE: for BTAMP case, it is being handled in limProcessMlmAssocReq
*/
- if (!((psessionEntry->bssType == eSIR_BTAMP_STA_MODE) ||
- ((psessionEntry->bssType == eSIR_BTAMP_AP_MODE) &&
- (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE))))
- {
- if (limSetLinkState(pMac, eSIR_LINK_POSTASSOC_STATE, psessionEntry->bssId,
- psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS)
+ if (!pMac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+ if (!((psessionEntry->bssType == eSIR_BTAMP_STA_MODE) ||
+ ((psessionEntry->bssType == eSIR_BTAMP_AP_MODE) &&
+ (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE))))
+ {
+ if (limSetLinkState(pMac, eSIR_LINK_POSTASSOC_STATE,
+ psessionEntry->bssId,
+ psessionEntry->selfMacAddr,
+ NULL, NULL) != eSIR_SUCCESS)
{
PELOGE(limLog(pMac, LOGE, FL("Set link state to POSTASSOC failed"));)
vos_mem_free(pBeaconStruct);
vos_mem_free(pAssocRsp);
return;
}
+ }
}
if (subType == LIM_REASSOC)
{
@@ -776,6 +800,21 @@ limProcessAssocRspFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tANI_U8 sub
goto assocReject;
}
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+ limLog(pMac, LOG1, FL("Reassoc success for LFR MBB in state %d"),
+ psessionEntry->limMlmState);
+ if (psessionEntry->limMlmState ==
+ eLIM_MLM_WT_REASSOC_RSP_STATE) {
+ lim_handle_reassoc_mbb_success(pMac, psessionEntry,
+ pAssocRsp, pStaDs);
+ return;
+ }
+ goto assocReject;
+ }
+#endif
+
+
#if defined(WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
if (psessionEntry->limMlmState == eLIM_MLM_WT_FT_REASSOC_RSP_STATE)
{
@@ -882,6 +921,18 @@ limProcessAssocRspFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tANI_U8 sub
GET_IE_LEN_IN_BSS(psessionEntry->pLimJoinReq->bssDescription.length),
pBeaconStruct);
+ if (pBeaconStruct->VHTCaps.present)
+ pStaDs->parsed_ies.vht_caps = pBeaconStruct->VHTCaps;
+ if (pBeaconStruct->HTCaps.present)
+ pStaDs->parsed_ies.ht_caps = pBeaconStruct->HTCaps;
+ if (pBeaconStruct->hs20vendor_ie.present)
+ pStaDs->parsed_ies.hs20vendor_ie =
+ pBeaconStruct->hs20vendor_ie;
+ if (pBeaconStruct->HTInfo.present)
+ pStaDs->parsed_ies.ht_operation = pBeaconStruct->HTInfo;
+ if (pBeaconStruct->VHTOperation.present)
+ pStaDs->parsed_ies.vht_operation = pBeaconStruct->VHTOperation;
+
if(pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
limDecideStaProtectionOnAssoc(pMac, pBeaconStruct, psessionEntry);
@@ -962,6 +1013,14 @@ assocReject:
}
#endif /* WLAN_FEATURE_VOWIFI_11R */
} else {
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+ lim_handle_reassoc_mbb_fail(pMac, psessionEntry);
+ vos_mem_free(pBeaconStruct);
+ vos_mem_free(pAssocRsp);
+ return;
+ }
+#endif
limRestorePreReassocState( pMac,
eSIR_SME_REASSOC_REFUSED, mlmAssocCnf.protStatusCode,psessionEntry);
}
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessAuthFrame.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessAuthFrame.c
index 0f1ee26b701..04d676d8139 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessAuthFrame.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessAuthFrame.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2015, 2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -51,6 +51,9 @@
#include "limFT.h"
#endif
#include "vos_utils.h"
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "lim_mbb.h"
+#endif
/**
@@ -218,19 +221,13 @@ limProcessAuthFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession pse
goto free;
}
- encrAuthFrame = vos_mem_malloc(LIM_ENCR_AUTH_BODY_LEN);
- if (!encrAuthFrame) {
- limLog(pMac, LOGE, FL("failed to allocate memory"));
- goto free;
- }
-
plainBody = vos_mem_malloc(LIM_ENCR_AUTH_BODY_LEN);
if (!plainBody) {
limLog(pMac, LOGE, FL("failed to allocate memory"));
goto free;
}
- challengeTextArray = vos_mem_malloc(SIR_MAC_AUTH_CHALLENGE_LENGTH);
+ challengeTextArray = vos_mem_malloc(SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH);
if(!challengeTextArray) {
limLog(pMac, LOGE, FL("failed to allocate memory"));
goto free;
@@ -238,9 +235,8 @@ limProcessAuthFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession pse
vos_mem_set(rxAuthFrame, sizeof(tSirMacAuthFrameBody), 0);
vos_mem_set(authFrame, sizeof(tSirMacAuthFrameBody), 0);
- vos_mem_set(encrAuthFrame, LIM_ENCR_AUTH_BODY_LEN, 0);
vos_mem_set(plainBody, LIM_ENCR_AUTH_BODY_LEN, 0);
- vos_mem_set(challengeTextArray, SIR_MAC_AUTH_CHALLENGE_LENGTH, 0);
+ vos_mem_set(challengeTextArray, SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH, 0);
/// Determine if WEP bit is set in the FC or received MAC header
if (pHdr->fc.wep)
@@ -291,7 +287,7 @@ limProcessAuthFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession pse
goto free;
}
- if (frameLen < LIM_ENCR_AUTH_BODY_LEN)
+ if (frameLen < LIM_ENCR_AUTH_BODY_LEN_SAP)
{
// Log error
limLog(pMac, LOGE,
@@ -997,7 +993,7 @@ limProcessAuthFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession pse
/*
* get random bytes and use as challenge text
*/
- if( !VOS_IS_STATUS_SUCCESS( vos_rand_get_bytes( 0, (tANI_U8 *)challengeTextArray, SIR_MAC_AUTH_CHALLENGE_LENGTH ) ) )
+ if( !VOS_IS_STATUS_SUCCESS( vos_rand_get_bytes( 0, (tANI_U8 *)challengeTextArray, SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH ) ) )
{
limLog(pMac, LOGE,FL("Challenge text "
"preparation failed in limProcessAuthFrame"));
@@ -1021,10 +1017,10 @@ limProcessAuthFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession pse
authFrame->authStatusCode =
eSIR_MAC_SUCCESS_STATUS;
authFrame->type = SIR_MAC_CHALLENGE_TEXT_EID;
- authFrame->length = SIR_MAC_AUTH_CHALLENGE_LENGTH;
+ authFrame->length = SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH;
vos_mem_copy(authFrame->challengeText,
pAuthNode->challengeText,
- SIR_MAC_AUTH_CHALLENGE_LENGTH);
+ SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH);
limSendAuthMgmtFrame(
pMac, authFrame,
@@ -1317,10 +1313,19 @@ limProcessAuthFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession pse
sirSwapU16ifNeeded((tANI_U16) (pRxAuthFrameBody->authTransactionSeqNumber + 1));
((tpSirMacAuthFrameBody) plainBody)->authStatusCode = eSIR_MAC_SUCCESS_STATUS;
((tpSirMacAuthFrameBody) plainBody)->type = SIR_MAC_CHALLENGE_TEXT_EID;
- ((tpSirMacAuthFrameBody) plainBody)->length = SIR_MAC_AUTH_CHALLENGE_LENGTH;
+ ((tpSirMacAuthFrameBody) plainBody)->length = pRxAuthFrameBody->length;
vos_mem_copy((tANI_U8 *) ((tpSirMacAuthFrameBody) plainBody)->challengeText,
pRxAuthFrameBody->challengeText,
- SIR_MAC_AUTH_CHALLENGE_LENGTH);
+ pRxAuthFrameBody->length);
+
+ encrAuthFrame = vos_mem_malloc(pRxAuthFrameBody->length +
+ LIM_ENCR_AUTH_INFO_LEN);
+ if (!encrAuthFrame) {
+ limLog(pMac, LOGE, FL("failed to allocate memory"));
+ goto free;
+ }
+ vos_mem_set(encrAuthFrame, pRxAuthFrameBody->length +
+ LIM_ENCR_AUTH_INFO_LEN, 0);
limEncryptAuthFrame(pMac, 0,
pKeyMapEntry->key,
@@ -1333,7 +1338,7 @@ limProcessAuthFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession pse
limSendAuthMgmtFrame(pMac,
(tpSirMacAuthFrameBody) encrAuthFrame,
pHdr->sa,
- LIM_WEP_IN_FC,
+ pRxAuthFrameBody->length,
psessionEntry, eSIR_FALSE);
break;
@@ -1397,10 +1402,19 @@ limProcessAuthFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession pse
sirSwapU16ifNeeded((tANI_U16) (pRxAuthFrameBody->authTransactionSeqNumber + 1));
((tpSirMacAuthFrameBody) plainBody)->authStatusCode = eSIR_MAC_SUCCESS_STATUS;
((tpSirMacAuthFrameBody) plainBody)->type = SIR_MAC_CHALLENGE_TEXT_EID;
- ((tpSirMacAuthFrameBody) plainBody)->length = SIR_MAC_AUTH_CHALLENGE_LENGTH;
+ ((tpSirMacAuthFrameBody) plainBody)->length = pRxAuthFrameBody->length;
vos_mem_copy((tANI_U8 *) ((tpSirMacAuthFrameBody) plainBody)->challengeText,
pRxAuthFrameBody->challengeText,
- SIR_MAC_AUTH_CHALLENGE_LENGTH);
+ pRxAuthFrameBody->length);
+
+ encrAuthFrame = vos_mem_malloc(pRxAuthFrameBody->length +
+ LIM_ENCR_AUTH_INFO_LEN);
+ if (!encrAuthFrame) {
+ limLog(pMac, LOGE, FL("failed to allocate memory"));
+ goto free;
+ }
+ vos_mem_set(encrAuthFrame, pRxAuthFrameBody->length +
+ LIM_ENCR_AUTH_INFO_LEN, 0);
limEncryptAuthFrame(pMac, keyId,
defaultKey,
@@ -1414,7 +1428,7 @@ limProcessAuthFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession pse
limSendAuthMgmtFrame(pMac,
(tpSirMacAuthFrameBody) encrAuthFrame,
pHdr->sa,
- LIM_WEP_IN_FC,
+ pRxAuthFrameBody->length,
psessionEntry, eSIR_FALSE);
break;
@@ -1588,7 +1602,7 @@ limProcessAuthFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession pse
if (vos_mem_compare(pRxAuthFrameBody->challengeText,
pAuthNode->challengeText,
- SIR_MAC_AUTH_CHALLENGE_LENGTH))
+ SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH))
{
/// Challenge match. STA is autheticated !
@@ -1924,15 +1938,33 @@ tSirRetStatus limProcessAuthFrameNoSession(tpAniSirGlobal pMac, tANI_U8 *pBd, vo
limLog(pMac, LOG1, FL("Pre-Auth response received from neighbor"));
limLog(pMac, LOG1, FL("Pre-Auth done state"));
#endif
+
+ limLog(pMac, LOG1, FL("is_preauth_lfr_mbb %d"),
+ pMac->ft.ftSmeContext.is_preauth_lfr_mbb);
+
// Stopping timer now, that we have our unicast from the AP
// of our choice.
- limDeactivateAndChangeTimer(pMac, eLIM_FT_PREAUTH_RSP_TIMER);
+ if (!pMac->ft.ftSmeContext.is_preauth_lfr_mbb)
+ limDeactivateAndChangeTimer(pMac, eLIM_FT_PREAUTH_RSP_TIMER);
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb)
+ limDeactivateAndChangeTimer(pMac, eLIM_PREAUTH_MBB_RSP_TIMER);
+#endif
// Save off the auth resp.
if ((sirConvertAuthFrame2Struct(pMac, pBody, frameLen, &rxAuthFrame) != eSIR_SUCCESS))
{
limLog(pMac, LOGE, FL("failed to convert Auth frame to struct"));
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+ lim_handle_pre_auth_mbb_rsp(pMac, eSIR_FAILURE, psessionEntry);
+ return eSIR_FAILURE;
+ }
+#endif
+
limHandleFTPreAuthRsp(pMac, eSIR_FAILURE, NULL, 0, psessionEntry);
return eSIR_FAILURE;
}
@@ -1972,6 +2004,13 @@ tSirRetStatus limProcessAuthFrameNoSession(tpAniSirGlobal pMac, tANI_U8 *pBd, vo
break;
}
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+ lim_handle_pre_auth_mbb_rsp(pMac, ret_status, psessionEntry);
+ return ret_status;
+ }
+#endif
+
// Send the Auth response to SME
limHandleFTPreAuthRsp(pMac, ret_status, pBody, frameLen, psessionEntry);
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c
index a7d4df8fa24..ef1056e7392 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014, 2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -36,6 +36,9 @@
#include "limSerDesUtils.h"
#include "schApi.h"
#include "limSendMessages.h"
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "lim_mbb.h"
+#endif
@@ -77,7 +80,6 @@ limProcessDeauthFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession p
pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
-
if ((eLIM_STA_ROLE == psessionEntry->limSystemRole) && (eLIM_SME_WT_DEAUTH_STATE == psessionEntry->limSmeState))
{
/*Every 15th deauth frame will be logged in kmsg*/
@@ -229,6 +231,14 @@ limProcessDeauthFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession p
{
pRoamSessionEntry = peFindSessionByBssid(pMac, psessionEntry->limReAssocbssId, &roamSessionId);
}
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (lim_is_mbb_reassoc_in_progress(pMac, psessionEntry)) {
+ limLog(pMac, LOGE, FL("Ignore Deauth frame as LFR MBB in progress"));
+ return;
+ }
+#endif
+
if (limIsReassocInProgress(pMac,psessionEntry) || limIsReassocInProgress(pMac,pRoamSessionEntry)) {
if (!IS_REASSOC_BSSID(pMac,pHdr->sa,psessionEntry)) {
PELOGE(limLog(pMac, LOGE, FL("Rcv Deauth from unknown/different "
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessDisassocFrame.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessDisassocFrame.c
index 6483854d07c..88585abac91 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessDisassocFrame.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessDisassocFrame.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -49,6 +49,9 @@
#include "limSerDesUtils.h"
#include "limSendMessages.h"
#include "schApi.h"
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "lim_mbb.h"
+#endif
/**
@@ -84,7 +87,6 @@ limProcessDisassocFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession
pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
-
if (limIsGroupAddr(pHdr->sa))
{
// Received Disassoc frame from a BC/MC address
@@ -160,6 +162,13 @@ limProcessDisassocFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession
return;
}
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (lim_is_mbb_reassoc_in_progress(pMac, psessionEntry)) {
+ limLog(pMac, LOGE, FL("Ignore Disassoc frame as LFR MBB in progress"));
+ return;
+ }
+#endif
+
/** If we are in the Wait for ReAssoc Rsp state */
if (limIsReassocInProgress(pMac,psessionEntry)) {
/** If we had received the DisAssoc from,
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
index e8b9fced0b3..ddb9f5fa481 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -516,7 +516,7 @@ limCheckMgmtRegisteredFrames(tpAniSirGlobal pMac, tANI_U8 *pBd,
/* Indicate this to SME */
limSendSmeMgmtFrameInd( pMac, pLimMgmtRegistration->sessionId,
- pBd, psessionEntry, 0);
+ pBd, psessionEntry, WDA_GET_RX_RSSI_DB(pBd));
if ( (type == SIR_MAC_MGMT_FRAME) && (fc.type == SIR_MAC_MGMT_FRAME)
&& (subType == SIR_MAC_MGMT_RESERVED15) )
@@ -679,6 +679,71 @@ limProcessEXTScanRealTimeData(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo)
} /*** end limProcessEXTScanRealTimeData() ***/
#endif /* WLAN_FEATURE_EXTSCAN */
+#ifdef SAP_AUTH_OFFLOAD
+/*
+ * lim_process_sap_offload_indication: function to process add sta/ del sta
+ * indication for SAP auth offload.
+ *
+ * @pMac: mac context
+ * @pRxPacketInfo: rx buffer
+ *
+ * This Function will go through buffer and if
+ * indication type is ADD_STA_IND, function will extract all data related to
+ * client and will call limAddSta
+ * and if indication type is DEL_STA_IND, function will call
+ * limSendSmeDisassocInd to do cleanup for station.
+ *
+ * Return : none
+ */
+static void lim_process_sap_offload_indication(tpAniSirGlobal pMac,
+ tANI_U8 *pRxPacketInfo)
+{
+ int i = 0;
+ tSapOfldIndications *sap_offload_indication_rx_buf =
+ (tSapOfldIndications *)WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
+ tSapOfldInd *sap_offload_ind =
+ (tSapOfldInd*)sap_offload_indication_rx_buf->indications;
+
+ limLog( pMac, LOG1,
+ FL("Notify SME with Sap Offload ind and indication type is %d num_indication %d \n"),
+ sap_offload_ind->indType,
+ (tANI_U8) sap_offload_indication_rx_buf->num_indications);
+
+ for (i=1; i <= (tANI_U8)(sap_offload_indication_rx_buf->num_indications);
+ i++)
+ {
+ if (sap_offload_ind->indType == SAP_OFFLOAD_ADD_STA_IND)
+ {
+ tSapOfldAddStaIndMsg *add_sta;
+ limLog( pMac, LOG1,
+ FL("Indication type is SAP_OFFLOAD_ADD_STA_IND"));
+ add_sta = (tSapOfldAddStaIndMsg *)sap_offload_ind->indication;
+ lim_sap_offload_add_sta(pMac, add_sta);
+ if (sap_offload_indication_rx_buf->num_indications > 1)
+ sap_offload_ind =
+ (tSapOfldInd *)((tANI_U8 *)sap_offload_ind +
+ sizeof(tSapOfldAddStaIndMsg) - sizeof(tANI_U8)+
+ add_sta->data_len + sizeof(tANI_U32));
+ }
+ else if (sap_offload_ind->indType == SAP_OFFLOAD_DEL_STA_IND)
+ {
+ tSapOfldDelStaIndMsg *del_sta;
+ limLog( pMac, LOG1,
+ FL("Indication type is SAP_OFFLOAD_DEL_STA_IND"));
+ del_sta = (tSapOfldDelStaIndMsg *)sap_offload_ind->indication;
+ lim_sap_offload_del_sta(pMac, del_sta);
+ sap_offload_ind = (tSapOfldInd *)((tANI_U8 *)sap_offload_ind +
+ sizeof(tSapOfldDelStaIndMsg) + sizeof(tANI_U32));
+ }
+ else
+ {
+ limLog(pMac, LOGE, FL("No Valid indication for connected station"));
+ }
+ }
+
+}
+#endif
+
/**
* limHandle80211Frames()
*
@@ -711,10 +776,20 @@ limHandle80211Frames(tpAniSirGlobal pMac, tpSirMsgQ limMsg, tANI_U8 *pDeferMsg)
tANI_U8 sessionId;
tAniBool isFrmFt = FALSE;
tANI_U16 fcOffset = WLANHAL_RX_BD_HEADER_SIZE;
+ tANI_S8 pe_sessionid = -1;
*pDeferMsg= false;
limGetBDfromRxPacket(pMac, limMsg->bodyptr, (tANI_U32 **)&pRxPacketInfo);
+#ifdef SAP_AUTH_OFFLOAD
+ if ((WDA_GET_SAP_AUTHOFFLOADIND(pRxPacketInfo) == 1) &&
+ pMac->sap_auth_offload)
+ {
+ lim_process_sap_offload_indication(pMac, pRxPacketInfo);
+ goto end;
+ }
+#endif
+
#ifdef WLAN_FEATURE_EXTSCAN
if ( WDA_GET_EXTSCANFULLSCANRESIND(pRxPacketInfo))
@@ -801,6 +876,24 @@ limHandle80211Frames(tpAniSirGlobal pMac, tpSirMsgQ limMsg, tANI_U8 *pDeferMsg)
pMac->PERroamCandidatesCnt = 0;
}
+ pe_sessionid = limGetInfraSessionId(pMac);
+ if (pe_sessionid != -1) {
+ psessionEntry = peFindSessionBySessionId(pMac, pe_sessionid);
+ if (psessionEntry != NULL)
+ {
+ if ((psessionEntry->limSmeState == eLIM_SME_WT_DEAUTH_STATE) ||
+ (psessionEntry->limSmeState == eLIM_SME_WT_DISASSOC_STATE))
+ {
+ limLog(pMac, LOG1,
+ FL("Drop candidate ind as deauth/disassoc in progress"));
+ goto end;
+ }
+ }
+ }
+ else
+ limLog(pMac, LOGE,
+ FL("session id doesn't exist for infra"));
+
//send a session 0 for now - TBD
limSendSmeCandidateFoundInd(pMac, 0);
goto end;
@@ -1607,6 +1700,9 @@ limProcessMessages(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
case eWNI_SME_FT_PRE_AUTH_REQ:
case eWNI_SME_FT_AGGR_QOS_REQ:
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+ case eWNI_SME_MBB_PRE_AUTH_REASSOC_REQ:
+#endif
case eWNI_SME_ADD_STA_SELF_REQ:
case eWNI_SME_DEL_STA_SELF_REQ:
case eWNI_SME_REGISTER_MGMT_FRAME_REQ:
@@ -1625,7 +1721,6 @@ limProcessMessages(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
case eWNI_SME_MAC_SPOOF_ADDR_IND:
case eWNI_SME_REGISTER_MGMT_FRAME_CB:
- case eWNI_SME_DEL_TEST_BA:
// These messages are from HDD
limProcessNormalHddMsg(pMac, limMsg, false); //no need to response to hdd
break;
@@ -1827,6 +1922,11 @@ limProcessMessages(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
limHandleBmpsStatusInd(pMac);
break;
+#ifdef WLAN_FEATURE_APFIND
+ case WDA_AP_FIND_IND:
+ limHandleAPFindInd(pMac);
+ break;
+#endif
case WDA_MISSED_BEACON_IND:
limHandleMissedBeaconInd(pMac, limMsg);
vos_mem_free(limMsg->bodyptr);
@@ -1908,6 +2008,10 @@ limProcessMessages(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
case SIR_LIM_DEAUTH_ACK_TIMEOUT:
case SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE:
case SIR_LIM_AUTH_RETRY_TIMEOUT:
+#ifdef WLAN_FEATURE_LFR_MBB
+ case SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT:
+ case SIR_LIM_REASSOC_MBB_RSP_TIMEOUT:
+#endif
// These timeout messages are handled by MLM sub module
limProcessMlmReqMessages(pMac,
@@ -2419,6 +2523,22 @@ send_chan_switch_resp:
limMsg->bodyptr = NULL;
break;
+ case eWNI_SME_CAP_TSF_REQ:
+ lim_process_sme_cap_tsf_req(pMac, limMsg->bodyptr);
+ vos_mem_free((v_VOID_t*)limMsg->bodyptr);
+ limMsg->bodyptr = NULL;
+ break;
+
+ case eWNI_SME_GET_TSF_REQ:
+ lim_process_sme_get_tsf_req(pMac, limMsg->bodyptr);
+ vos_mem_free((v_VOID_t*)limMsg->bodyptr);
+ limMsg->bodyptr = NULL;
+ break;
+ case eWNI_SME_DEL_BA_SES_REQ:
+ lim_process_sme_del_ba_ses_req(pMac, limMsg->bodyptr);
+ vos_mem_free((v_VOID_t*)limMsg->bodyptr);
+ limMsg->bodyptr = NULL;
+ break;
default:
vos_mem_free((v_VOID_t*)limMsg->bodyptr);
limMsg->bodyptr = NULL;
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c
index d0eab9bab7b..2e382d9dee9 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -59,6 +59,9 @@
#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
#include "vos_diag_core_log.h"
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "lim_mbb.h"
+#endif
// MLM REQ processing function templates
@@ -155,6 +158,14 @@ limProcessMlmReqMessages(tpAniSirGlobal pMac, tpSirMsgQ Msg)
#ifdef WLAN_FEATURE_VOWIFI_11R
case SIR_LIM_FT_PREAUTH_RSP_TIMEOUT:limProcessFTPreauthRspTimeout(pMac); break;
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+ case SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT:
+ lim_process_preauth_mbb_rsp_timeout(pMac);
+ break;
+ case SIR_LIM_REASSOC_MBB_RSP_TIMEOUT:
+ lim_process_reassoc_mbb_rsp_timeout(pMac);
+ break;
+#endif
case SIR_LIM_REMAIN_CHN_TIMEOUT: limProcessRemainOnChnTimeout(pMac); break;
case SIR_LIM_INSERT_SINGLESHOT_NOA_TIMEOUT:
limProcessInsertSingleShotNOATimeout(pMac); break;
@@ -762,8 +773,41 @@ void limSetDFSChannelList(tpAniSirGlobal pMac,tANI_U8 channelNum, tSirDFSChannel
return;
}
+void limDoSendAuthMgmtFrame(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ tSirMacAuthFrameBody authFrameBody;
-
+ //Prepare & send Authentication frame
+ authFrameBody.authAlgoNumber =
+ (tANI_U8) pMac->lim.gpLimMlmAuthReq->authType;
+ authFrameBody.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1;
+ authFrameBody.authStatusCode = 0;
+ pMac->authAckStatus = LIM_AUTH_ACK_NOT_RCD;
+ limSendAuthMgmtFrame(pMac,
+ &authFrameBody,
+ pMac->lim.gpLimMlmAuthReq->peerMacAddr,
+ LIM_NO_WEP_IN_FC, psessionEntry, eSIR_TRUE);
+ if (tx_timer_activate(&pMac->lim.limTimers.gLimAuthFailureTimer)
+ != TX_SUCCESS) {
+ //Could not start Auth failure timer.
+ //Log error
+ limLog(pMac, LOGP,
+ FL("could not start Auth failure timer"));
+ //Cleanup as if auth timer expired
+ limProcessAuthFailureTimeout(pMac);
+ } else {
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE,
+ psessionEntry->peSessionId, eLIM_AUTH_RETRY_TIMER));
+ //Activate Auth Retry timer
+ if (tx_timer_activate
+ (&pMac->lim.limTimers.gLimPeriodicAuthRetryTimer)
+ != TX_SUCCESS) {
+ limLog(pMac, LOGP,
+ FL("could not activate Auth Retry timer"));
+ }
+ }
+ return;
+}
/*
* Creates a Raw frame to be sent before every Scan, if required.
@@ -2386,7 +2430,6 @@ limProcessMlmAuthReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
tANI_U32 numPreAuthContexts;
tSirMacAddr currentBssId;
- tSirMacAuthFrameBody authFrameBody;
tLimMlmAuthCnf mlmAuthCnf;
struct tLimPreAuthNode *preAuthNode;
tpDphHashNode pStaDs;
@@ -2513,17 +2556,6 @@ limProcessMlmAuthReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
psessionEntry->limMlmState = eLIM_MLM_WT_AUTH_FRAME2_STATE;
MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState));
- /// Prepare & send Authentication frame
- authFrameBody.authAlgoNumber =
- (tANI_U8) pMac->lim.gpLimMlmAuthReq->authType;
- authFrameBody.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1;
- authFrameBody.authStatusCode = 0;
- pMac->authAckStatus = LIM_AUTH_ACK_NOT_RCD;
- limSendAuthMgmtFrame(pMac,
- &authFrameBody,
- pMac->lim.gpLimMlmAuthReq->peerMacAddr,
- LIM_NO_WEP_IN_FC, psessionEntry, eSIR_TRUE);
-
//assign appropriate sessionId to the timer object
pMac->lim.limTimers.gLimAuthFailureTimer.sessionId = sessionId;
/* assign appropriate sessionId to the timer object */
@@ -2531,27 +2563,8 @@ limProcessMlmAuthReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
limDeactivateAndChangeTimer(pMac, eLIM_AUTH_RETRY_TIMER);
// Activate Auth failure timer
MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_AUTH_FAIL_TIMER));
- if (tx_timer_activate(&pMac->lim.limTimers.gLimAuthFailureTimer)
- != TX_SUCCESS)
- {
- /// Could not start Auth failure timer.
- // Log error
- limLog(pMac, LOGP,
- FL("could not start Auth failure timer"));
- // Cleanup as if auth timer expired
- limProcessAuthFailureTimeout(pMac);
- }
- else
- {
- MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE,
- psessionEntry->peSessionId, eLIM_AUTH_RETRY_TIMER));
- // Activate Auth Retry timer
- if (tx_timer_activate(&pMac->lim.limTimers.gLimPeriodicAuthRetryTimer)
- != TX_SUCCESS)
- {
- limLog(pMac, LOGP, FL("could not activate Auth Retry timer"));
- }
- }
+
+ limDoSendAuthMgmtFrame(pMac, psessionEntry);
return;
}
else
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c
index 1393690c514..feb52accaf5 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -61,6 +61,10 @@
#include "wlan_qct_wda.h"
#include "vos_utils.h"
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "lim_mbb.h"
+#endif
+
static void limHandleSmeJoinResult(tpAniSirGlobal, tSirResultCodes, tANI_U16,tpPESession);
static void limHandleSmeReaasocResult(tpAniSirGlobal, tSirResultCodes, tANI_U16, tpPESession);
void limProcessMlmScanCnf(tpAniSirGlobal, tANI_U32 *);
@@ -1068,8 +1072,15 @@ limProcessMlmReassocInd(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
}
sirStoreU16N((tANI_U8 *) &pSirSmeReassocInd->messageType,
eWNI_SME_REASSOC_IND);
- limReassocIndSerDes(pMac, (tpLimMlmReassocInd) pMsgBuf,
- (tANI_U8 *) &(pSirSmeReassocInd->length), psessionEntry);
+ if (limReassocIndSerDes(pMac, (tpLimMlmReassocInd) pMsgBuf,
+ (tANI_U8 *) &(pSirSmeReassocInd->length),
+ psessionEntry, sizeof(tSirSmeReassocInd))
+ != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGE,FL(" Received SME message with invalid rem length"));
+ vos_mem_free(pSirSmeReassocInd);
+ return;
+ }
// Required for indicating the frames to upper layer
pSirSmeReassocInd->assocReqLength = ((tpLimMlmReassocInd) pMsgBuf)->assocReqLength;
@@ -1141,8 +1152,14 @@ limProcessMlmAuthInd(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
return;
}
limCopyU16((tANI_U8 *) &pSirSmeAuthInd->messageType, eWNI_SME_AUTH_IND);
- limAuthIndSerDes(pMac, (tpLimMlmAuthInd) pMsgBuf,
- (tANI_U8 *) &(pSirSmeAuthInd->length));
+ if (limAuthIndSerDes(pMac, (tpLimMlmAuthInd) pMsgBuf,
+ (tANI_U8 *) &(pSirSmeAuthInd->length),
+ sizeof(tSirSmeAuthInd)) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGE,FL(" Received SME message with invalid rem length"));
+ vos_mem_free(pSirSmeAuthInd);
+ return;
+ }
msgQ.type = eWNI_SME_AUTH_IND;
msgQ.bodyptr = pSirSmeAuthInd;
msgQ.bodyval = 0;
@@ -1968,6 +1985,12 @@ void limProcessMlmAddStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession
limProcessBtAmpApMlmAddStaRsp(pMac, limMsgQ,psessionEntry);
return;
}
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+ lim_process_sta_mlm_add_sta_rsp_mbb(pMac, limMsgQ, psessionEntry);
+ return;
+ }
+#endif
limProcessStaMlmAddStaRsp(pMac, limMsgQ,psessionEntry);
}
void limProcessStaMlmAddStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ,tpPESession psessionEntry)
@@ -2145,6 +2168,13 @@ void limProcessStaMlmDelBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESessi
tpDphHashNode pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
tSirResultCodes statusCode = eSIR_SME_SUCCESS;
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+ lim_process_sta_mlm_del_bss_rsp_mbb(pMac, limMsgQ, psessionEntry);
+ return;
+ }
+#endif
+
if (NULL == pDelBssParams)
{
limLog( pMac, LOGE, FL( "Invalid body pointer in message"));
@@ -2418,6 +2448,13 @@ void limProcessStaMlmDelStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESessi
tpDeleteStaParams pDelStaParams = (tpDeleteStaParams) limMsgQ->bodyptr;
tpDphHashNode pStaDs = NULL;
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+ lim_process_sta_mlm_del_sta_rsp_mbb(pMac, limMsgQ, psessionEntry);
+ return;
+ }
+#endif
+
if(NULL == pDelStaParams )
{
limLog( pMac, LOGE, FL( "Encountered NULL Pointer" ));
@@ -3417,9 +3454,16 @@ void limProcessMlmAddBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ )
else
limProcessApMlmAddBssRsp( pMac,limMsgQ);
}
- else
+ else {
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+ lim_process_sta_mlm_add_bss_rsp_mbb(pMac, limMsgQ, psessionEntry);
+ return;
+ }
+#endif
/* Called while processing assoc response */
limProcessStaMlmAddBssRsp( pMac, limMsgQ,psessionEntry);
+ }
}
if(limIsInMCC(pMac))
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessProbeReqFrame.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessProbeReqFrame.c
index 81b112e6dd4..a3d8ef423d5 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessProbeReqFrame.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessProbeReqFrame.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -669,7 +669,7 @@ limIndicateProbeReqToHDD(tpAniSirGlobal pMac, tANI_U8 *pBd,
//send the probe req to SME.
limSendSmeMgmtFrameInd( pMac, psessionEntry->smeSessionId, pBd,
- psessionEntry, 0);
+ psessionEntry, WDA_GET_RX_RSSI_DB(pBd));
#ifdef WLAN_FEATURE_P2P_INTERNAL
limSendP2PProbeResponse(pMac, pBd, psessionEntry);
#endif
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
index cead21d75b1..346585cf75e 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
@@ -76,6 +76,10 @@
#include <limFT.h>
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "lim_mbb.h"
+#endif
+
#define JOIN_FAILURE_TIMEOUT 1000 // in msecs
/* This overhead is time for sending NOA start to host in case of GO/sending NULL data & receiving ACK
@@ -243,7 +247,7 @@ __limIsSmeAssocCnfValid(tpSirSmeAssocCnf pAssocCnf)
* @return Total IE length
*/
-static tANI_U16
+tANI_U16
__limGetSmeJoinReqSizeForAlloc(tANI_U8 *pBuf)
{
tANI_U16 len = 0;
@@ -1939,6 +1943,7 @@ __limProcessSmeJoinReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
handleHTCapabilityandHTInfo(pMac, psessionEntry);
/* Copy The channel Id to the session Table */
psessionEntry->currentOperChannel = pSmeJoinReq->bssDescription.channelId;
+ psessionEntry->force_24ghz_in_ht20 = pSmeJoinReq->force_24ghz_in_ht20;
psessionEntry->htSupportedChannelWidthSet = (pSmeJoinReq->cbMode)?1:0; // This is already merged value of peer and self - done by csr in csrGetCBModeFromIes
psessionEntry->htRecommendedTxWidthSet = psessionEntry->htSupportedChannelWidthSet;
psessionEntry->htSecondaryChannelOffset = pSmeJoinReq->cbMode;
@@ -1962,8 +1967,10 @@ __limProcessSmeJoinReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
/*Store Persona */
psessionEntry->pePersona = pSmeJoinReq->staPersona;
VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
- FL("PE PERSONA=%d cbMode %u"), psessionEntry->pePersona,
- pSmeJoinReq->cbMode);
+ FL("PE PERSONA=%d cbMode %u force_24ghz_in_ht20 %d"),
+ psessionEntry->pePersona,
+ pSmeJoinReq->cbMode,
+ psessionEntry->force_24ghz_in_ht20);
/* Copy the SSID from smejoinreq to session entry */
psessionEntry->ssId.length = pSmeJoinReq->ssId.length;
@@ -2088,6 +2095,14 @@ __limProcessSmeJoinReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
" max tx = %d", regMax, localPowerConstraint,
psessionEntry->maxTxPower );
+ if (pSmeJoinReq->powerCap.maxTxPower > psessionEntry->maxTxPower)
+ {
+ pSmeJoinReq->powerCap.maxTxPower = psessionEntry->maxTxPower;
+ VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
+ "Update MaxTxPower in join Req to %d",
+ pSmeJoinReq->powerCap.maxTxPower);
+ }
+
if (pMac->lim.gLimCurrentBssUapsd)
{
pMac->lim.gUapsdPerAcBitmask = psessionEntry->pLimJoinReq->uapsdPerAcBitmask;
@@ -4018,8 +4033,10 @@ __limProcessSmeAssocCnfNew(tpAniSirGlobal pMac, tANI_U32 msgType, tANI_U32 *pMsg
*/
pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
limLog(pMac, LOG1, FL("sending Assoc Rsp frame to STA (assoc id=%d) "), pStaDs->assocId);
- limSendAssocRspMgmtFrame( pMac, eSIR_SUCCESS, pStaDs->assocId, pStaDs->staAddr,
- pStaDs->mlmStaContext.subType, pStaDs, psessionEntry);
+ limSendAssocRspMgmtFrame(pMac, eSIR_SUCCESS, pStaDs->assocId,
+ pStaDs->staAddr,
+ pStaDs->mlmStaContext.subType, pStaDs,
+ psessionEntry, NULL);
goto end;
} // (assocCnf.statusCode == eSIR_SME_SUCCESS)
else
@@ -4056,7 +4073,99 @@ end:
} /*** end __limProcessSmeAssocCnfNew() ***/
+#ifdef SAP_AUTH_OFFLOAD
+/**
+ * __lim_process_sme_assoc_offload_cnf() station connection confirmation
+ * message from SME.
+ * @pMac: SirGlobal handler
+ * @msgType: message type
+ * @pMsgBuf: message body
+ *
+ * This function handles the station connect confirm of
+ * Software AP authentication offload feature
+ *
+ * Return: None
+ */
+ static void
+__lim_process_sme_assoc_offload_cnf(tpAniSirGlobal pmac,
+ tANI_U32 msg_type,
+ tANI_U32 *pmsg_buf)
+{
+ tSirSmeAssocCnf assoc_cnf;
+ tpDphHashNode sta_ds = NULL;
+ tpPESession psession_entry= NULL;
+ tANI_U8 session_id;
+ tANI_U16 aid=0;
+
+ if (pmsg_buf == NULL)
+ {
+ limLog(pmac, LOGE, FL("pmsg_buf is NULL "));
+ return;
+ }
+
+ if ((limAssocCnfSerDes(pmac, &assoc_cnf, (tANI_U8 *) pmsg_buf) ==
+ eSIR_FAILURE) || !__limIsSmeAssocCnfValid(&assoc_cnf))
+ {
+ limLog(pmac, LOGE, FL("Received invalid SME_RE(ASSOC)_CNF message "));
+ return;
+ }
+ if((psession_entry =
+ peFindSessionByBssid(pmac, assoc_cnf.bssId, &session_id))== NULL)
+ {
+ limLog(pmac, LOGE, FL("session does not exist for given bssId"));
+ goto end;
+ }
+
+ if ((!LIM_IS_AP_ROLE(psession_entry)) ||
+ ((psession_entry->limSmeState != eLIM_SME_NORMAL_STATE) &&
+ (psession_entry->limSmeState != eLIM_SME_NORMAL_CHANNEL_SCAN_STATE)))
+ {
+ limLog(pmac, LOGE,
+ FL("Received unexpected message %X in state %X, in role %X"),
+ msg_type, psession_entry->limSmeState,
+ GET_LIM_SYSTEM_ROLE(psession_entry));
+ goto end;
+ }
+ sta_ds = dphGetHashEntry(pmac,
+ assoc_cnf.aid,
+ &psession_entry->dph.dphHashTable);
+ if (sta_ds != NULL)
+ {
+ aid = sta_ds->assocId;
+ /* Deactivate/delete CNF_WAIT timer since ASSOC_CNF
+ * has been received */
+ limDeactivateAndChangePerStaIdTimer(pmac,
+ eLIM_CNF_WAIT_TIMER,
+ aid);
+ }
+ if (assoc_cnf.statusCode == eSIR_SME_SUCCESS)
+ {
+ sta_ds->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
+ limLog(pmac, LOG1, FL("Set mlmState to eLIM_MLM_LINK_ESTABLISHED_STATE"));
+ }
+
+end:
+ if((psession_entry != NULL) && (sta_ds != NULL))
+ {
+ if ( psession_entry->parsedAssocReq[aid] != NULL )
+ {
+ if ( ((tpSirAssocReq)
+ (psession_entry->parsedAssocReq[aid]))->assocReqFrame)
+ {
+ vos_mem_free(((tpSirAssocReq)
+ (psession_entry->parsedAssocReq[aid]))->assocReqFrame);
+ ((tpSirAssocReq)
+ (psession_entry->parsedAssocReq[aid]))->assocReqFrame =
+ NULL;
+ }
+ vos_mem_free(psession_entry->parsedAssocReq[aid]);
+ psession_entry->parsedAssocReq[aid] = NULL;
+ }
+ }
+
+} /*** end __lim_process_sme_assoc_offload_cnf() ***/
+#endif /* SAP_AUTH_OFFLOAD */
static void
@@ -5519,57 +5628,6 @@ static void lim_register_mgmt_frame_ind_cb(tpAniSirGlobal pMac,
limLog(pMac, LOGE, FL("sme_req->callback is null"));
}
-static void lim_delba_con_status(tpAniSirGlobal pMac,
- void *msg_buf)
-{
- tpSmeDelBAPeerInd delba_params;
- tpDphHashNode pSta;
- tANI_U16 aid;
- tLimBAState curBaState;
- tpPESession psessionEntry;
- tANI_U8 sessionId;
-
- delba_params = (tpSmeDelBAPeerInd)msg_buf;
-
- psessionEntry = peFindSessionByBssid(pMac, delba_params->bssId, &sessionId);
- if (!psessionEntry)
- {
- PELOGE(limLog(pMac, LOGE,FL("session does not exist for given BSSId"));)
- return;
- }
-
- pSta = dphLookupHashEntry(pMac, delba_params->bssId, &aid,
- &psessionEntry->dph.dphHashTable);
- if(!pSta)
- {
- limLog(pMac, LOGE,
- FL("STA context not found - ignoring BA Delete IND from HAL"));
- return;
- }
-
- LIM_GET_STA_BA_STATE(pSta, delba_params->baTID, &curBaState);
- if( eLIM_BA_STATE_IDLE != curBaState )
- {
- limLog(pMac, LOGE,
- FL("Received unexpected BA Delete IND when STA BA state is %d"),
- curBaState);
- return;
- }
-
- if(eSIR_SUCCESS != limPostMlmDelBAReq(pMac, pSta,
- delba_params->baDirection,
- delba_params->baTID,
- eSIR_MAC_PEER_REJECT_MECHANISIM_REASON,
- psessionEntry)) {
- limLog(pMac, LOGE, FL("Post DEL BA request failed"));
- }
- else
- {
- limLog(pMac, LOG1, FL(" Delete BA session StaId %d on tid %d"),
- delba_params->staIdx, delba_params->baTID);
- }
-}
-
/**
* limProcessSmeReqMessages()
*
@@ -5757,7 +5815,14 @@ limProcessSmeReqMessages(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
limLog(pMac, LOG1, FL("Received ASSOC_CNF message"));
else
limLog(pMac, LOG1, FL("Received REASSOC_CNF message"));
+#ifdef SAP_AUTH_OFFLOAD
+ if (pMac->sap_auth_offload)
+ __lim_process_sme_assoc_offload_cnf(pMac, pMsg->type, pMsgBuf);
+ else
+ __limProcessSmeAssocCnfNew(pMac, pMsg->type, pMsgBuf);
+#else
__limProcessSmeAssocCnfNew(pMac, pMsg->type, pMsgBuf);
+#endif /* SAP_AUTH_OFFLOAD */
break;
case eWNI_SME_ADDTS_REQ:
@@ -5859,6 +5924,13 @@ limProcessSmeReqMessages(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
break;
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+ case eWNI_SME_MBB_PRE_AUTH_REASSOC_REQ:
+ lim_process_pre_auth_reassoc_req(pMac, pMsg);
+ bufConsumed = FALSE;
+ break;
+#endif
+
#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD)
case eWNI_SME_ESE_ADJACENT_AP_REPORT:
limProcessAdjacentAPRepMsg ( pMac, pMsgBuf );
@@ -5916,9 +5988,6 @@ limProcessSmeReqMessages(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
case eWNI_SME_REGISTER_MGMT_FRAME_CB:
lim_register_mgmt_frame_ind_cb(pMac, pMsgBuf);
break;
- case eWNI_SME_DEL_TEST_BA:
- lim_delba_con_status(pMac, pMsgBuf);
- break;
default:
vos_mem_free((v_VOID_t*)pMsg->bodyptr);
pMsg->bodyptr = NULL;
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limPropExtsUtils.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limPropExtsUtils.c
index f4f668a916a..bd695ed9252 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limPropExtsUtils.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limPropExtsUtils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -203,6 +203,10 @@ limExtractApCapability(tpAniSirGlobal pMac, tANI_U8 *pIE, tANI_U16 ieLen,
}
}
+
+ /* Update HS 2.0 Information Element */
+ sir_copy_hs20_ie(&psessionEntry->hs20vendor_ie,
+ &pBeaconStruct->hs20vendor_ie);
vos_mem_free(pBeaconStruct);
return;
} /****** end limExtractApCapability() ******/
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSecurityUtils.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSecurityUtils.c
index ae588284b56..9f88436bf22 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSecurityUtils.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSecurityUtils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2015, 2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -473,10 +473,6 @@ limDeletePreAuthNode(tpAniSirGlobal pMac, tSirMacAddr macAddr)
} /*** end limDeletePreAuthNode() ***/
-
-
-
-
/**
* limRestoreFromPreAuthState
*
@@ -515,13 +511,6 @@ limRestoreFromAuthState(tpAniSirGlobal pMac, tSirResultCodes resultCode, tANI_U1
/* Update PE session ID*/
mlmAuthCnf.sessionId = sessionEntry->peSessionId;
-
- /// Free up buffer allocated
- /// for pMac->lim.gLimMlmAuthReq
- vos_mem_free(pMac->lim.gpLimMlmAuthReq);
- pMac->lim.gpLimMlmAuthReq = NULL;
-
- sessionEntry->limMlmState = sessionEntry->limPrevMlmState;
MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, sessionEntry->peSessionId, sessionEntry->limMlmState));
/* Set the authAckStatus status flag as sucess as
@@ -548,9 +537,25 @@ limRestoreFromAuthState(tpAniSirGlobal pMac, tSirResultCodes resultCode, tANI_U1
pMac->lim.gLimPreAuthChannelNumber = 0;
}
- limPostSmeMessage(pMac,
+ if ((protStatusCode == eSIR_MAC_MAX_ASSOC_STA_REACHED_STATUS)
+ && (sessionEntry->sta_auth_retries_for_code17 <
+ pMac->sta_auth_retries_for_code17)) {
+ limLog(pMac, LOG1, FL("Retry Auth "));
+ limDoSendAuthMgmtFrame(pMac, sessionEntry);
+ sessionEntry->sta_auth_retries_for_code17++;
+ } else {
+ /// Free up buffer allocated
+ /// for pMac->lim.gLimMlmAuthReq
+ vos_mem_free(pMac->lim.gpLimMlmAuthReq);
+ pMac->lim.gpLimMlmAuthReq = NULL;
+
+ sessionEntry->limMlmState = sessionEntry->limPrevMlmState;
+
+ limPostSmeMessage(pMac,
LIM_MLM_AUTH_CNF,
(tANI_U32 *) &mlmAuthCnf);
+ sessionEntry->sta_auth_retries_for_code17 = 0;
+ }
} /*** end limRestoreFromAuthState() ***/
@@ -614,7 +619,10 @@ limEncryptAuthFrame(tpAniSirGlobal pMac, tANI_U8 keyId, tANI_U8 *pKey, tANI_U8 *
tANI_U8 *pEncrBody, tANI_U32 keyLength)
{
tANI_U8 seed[LIM_SEED_LENGTH], icv[SIR_MAC_WEP_ICV_LENGTH];
+ tANI_U16 frame_len;
+ frame_len = ((tpSirMacAuthFrameBody)pPlainText)->length +
+ SIR_MAC_AUTH_FRAME_INFO_LEN + SIR_MAC_CHALLENGE_ID_LEN;
keyLength += 3;
// Bytes 0-2 of seed is IV
@@ -625,15 +633,15 @@ limEncryptAuthFrame(tpAniSirGlobal pMac, tANI_U8 keyId, tANI_U8 *pKey, tANI_U8 *
vos_mem_copy((tANI_U8 *) &seed[3], pKey, keyLength - 3);
// Compute CRC-32 and place them in last 4 bytes of plain text
- limComputeCrc32(icv, pPlainText, sizeof(tSirMacAuthFrameBody));
+ limComputeCrc32(icv, pPlainText, frame_len);
- vos_mem_copy( pPlainText + sizeof(tSirMacAuthFrameBody),
+ vos_mem_copy( pPlainText + frame_len,
icv, SIR_MAC_WEP_ICV_LENGTH);
// Run RC4 on plain text with the seed
limRC4(pEncrBody + SIR_MAC_WEP_IV_LENGTH,
(tANI_U8 *) pPlainText, seed, keyLength,
- LIM_ENCR_AUTH_BODY_LEN - SIR_MAC_WEP_IV_LENGTH);
+ frame_len + SIR_MAC_WEP_ICV_LENGTH);
// Prepare IV
pEncrBody[0] = seed[0];
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSecurityUtils.h b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSecurityUtils.h
index 1fc227478d7..2526f4e4c12 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSecurityUtils.h
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSecurityUtils.h
@@ -42,6 +42,18 @@
#define LIM_ENCR_AUTH_BODY_LEN (sizeof(tSirMacAuthFrameBody) + \
SIR_MAC_WEP_IV_LENGTH + \
SIR_MAC_WEP_ICV_LENGTH)
+
+#define LIM_ENCR_AUTH_BODY_LEN_SAP (SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH + \
+ SIR_MAC_CHALLENGE_ID_LEN + \
+ SIR_MAC_AUTH_FRAME_INFO_LEN + \
+ SIR_MAC_WEP_IV_LENGTH + \
+ SIR_MAC_WEP_ICV_LENGTH)
+
+#define LIM_ENCR_AUTH_INFO_LEN (SIR_MAC_AUTH_FRAME_INFO_LEN +\
+ SIR_MAC_WEP_IV_LENGTH + \
+ SIR_MAC_WEP_ICV_LENGTH + \
+ SIR_MAC_CHALLENGE_ID_LEN)
+
struct tLimPreAuthNode;
tANI_U8 limIsAuthAlgoSupported(tpAniSirGlobal, tAniAuthType, tpPESession);
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSendManagementFrames.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSendManagementFrames.c
index 1799c447e3b..feb335124a4 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSendManagementFrames.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSendManagementFrames.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -1384,7 +1384,8 @@ limSendAssocRspMgmtFrame(tpAniSirGlobal pMac,
tANI_U16 aid,
tSirMacAddr peerMacAddr,
tANI_U8 subType,
- tpDphHashNode pSta,tpPESession psessionEntry)
+ tpDphHashNode pSta,tpPESession psessionEntry,
+ assoc_rsp_tx_context *tx_complete_context)
{
static tDot11fAssocResponse frm;
tANI_U8 *pFrame, *macAddr;
@@ -1763,14 +1764,29 @@ limSendAssocRspMgmtFrame(tpAniSirGlobal pMac,
if (IS_FEATURE_SUPPORTED_BY_FW(ENHANCED_TXBD_COMPLETION))
{
- limLog(pMac, LOG1, FL("Re/AssocRsp - txBdToken %u"), pMac->lim.txBdToken);
+ limLog(pMac, LOG1, FL("Re/AssocRsp - txBdToken %u"),
+ pMac->lim.txBdToken);
/// Queue Association Response frame in high priority WQ
- halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes,
+ if (tx_complete_context)
+ {
+ tx_complete_context->txBdToken = pMac->lim.txBdToken;
+ halstatus = halTxFrameWithTxComplete(pMac, pPacket,
+ (tANI_U16) nBytes,
+ HAL_TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
+ limTxComplete, pFrame, limAssocRspTxCompleteCnf,
+ txFlag, pMac->lim.txBdToken);
+ }
+ else
+ halstatus = halTxFrameWithTxComplete(pMac, pPacket,
+ (tANI_U16) nBytes,
HAL_TXRX_FRM_802_11_MGMT,
ANI_TXDIR_TODS,
7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
limTxComplete, pFrame, limTxBdComplete,
- txFlag, pMac->lim.txBdToken );
+ txFlag, pMac->lim.txBdToken);
+
pMac->lim.txBdToken++;
}
else
@@ -3714,7 +3730,7 @@ void
limSendAuthMgmtFrame(tpAniSirGlobal pMac,
tpSirMacAuthFrameBody pAuthFrameBody,
tSirMacAddr peerMacAddr,
- tANI_U8 wepBit,
+ tANI_U8 wep_challenge_len,
tpPESession psessionEntry,
tAniBool waitForAck
)
@@ -3739,7 +3755,7 @@ limSendAuthMgmtFrame(tpAniSirGlobal pMac,
pAuthFrameBody->authStatusCode,
(pAuthFrameBody->authStatusCode == eSIR_MAC_SUCCESS_STATUS),
MAC_ADDR_ARRAY(peerMacAddr));
- if (wepBit == LIM_WEP_IN_FC)
+ if (wep_challenge_len)
{
/// Auth frame3 to be sent with encrypted framebody
/**
@@ -3749,10 +3765,8 @@ limSendAuthMgmtFrame(tpAniSirGlobal pMac,
* 128 bytes for challenge text and 4 bytes each for
* IV & ICV.
*/
-
- frameLen = sizeof(tSirMacMgmtHdr) + LIM_ENCR_AUTH_BODY_LEN;
-
- bodyLen = LIM_ENCR_AUTH_BODY_LEN;
+ bodyLen = wep_challenge_len + LIM_ENCR_AUTH_INFO_LEN;
+ frameLen = sizeof(tSirMacMgmtHdr) + bodyLen;
} // if (wepBit == LIM_WEP_IN_FC)
else
{
@@ -3817,9 +3831,11 @@ limSendAuthMgmtFrame(tpAniSirGlobal pMac,
* for challenge text.
*/
+ bodyLen = SIR_MAC_AUTH_FRAME_INFO_LEN +
+ SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH +
+ SIR_MAC_CHALLENGE_ID_LEN;
frameLen = sizeof(tSirMacMgmtHdr) +
- sizeof(tSirMacAuthFrame);
- bodyLen = sizeof(tSirMacAuthFrameBody);
+ bodyLen;
}
break;
@@ -3880,7 +3896,10 @@ limSendAuthMgmtFrame(tpAniSirGlobal pMac,
}
pMacHdr = ( tpSirMacMgmtHdr ) pFrame;
- pMacHdr->fc.wep = wepBit;
+ if (wep_challenge_len)
+ pMacHdr->fc.wep = LIM_WEP_IN_FC;
+ else
+ pMacHdr->fc.wep = LIM_NO_WEP_IN_FC;
// Prepare BSSId
if( (psessionEntry->limSystemRole == eLIM_AP_ROLE)|| (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) )
@@ -3893,7 +3912,7 @@ limSendAuthMgmtFrame(tpAniSirGlobal pMac,
/// Prepare Authentication frame body
pBody = pFrame + sizeof(tSirMacMgmtHdr);
- if (wepBit == LIM_WEP_IN_FC)
+ if (wep_challenge_len)
{
vos_mem_copy(pBody, (tANI_U8 *) pAuthFrameBody, bodyLen);
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c
index 85c577b1dd5..69d186eedd6 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -54,7 +54,7 @@
#include "limSendSmeRspMessages.h"
#include "limIbssPeerMgmt.h"
#include "limSessionUtils.h"
-
+#include "lim_mbb.h"
/**
* limSendSmeRsp()
@@ -160,6 +160,29 @@ limSendSmeRsp(tpAniSirGlobal pMac, tANI_U16 msgType,
limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
} /*** end limSendSmeRsp() ***/
+/**
+ * lim_add_bss_info() - copy data from session entry to join rsp
+ * @session_entry: PE Session Info
+ * @sme_join_rsp: Join response buffer to be filled up
+ *
+ * Return: None
+ */
+void lim_add_bss_info(tpDphHashNode sta_ds,
+ tpSirSmeJoinRsp sme_join_rsp)
+{
+ struct parsed_ies *parsed_ies = &sta_ds->parsed_ies;
+
+ if (parsed_ies->hs20vendor_ie.present)
+ sme_join_rsp->hs20vendor_ie = parsed_ies->hs20vendor_ie;
+ if (parsed_ies->vht_caps.present)
+ sme_join_rsp->vht_caps = parsed_ies->vht_caps;
+ if (parsed_ies->ht_caps.present)
+ sme_join_rsp->ht_caps = parsed_ies->ht_caps;
+ if (parsed_ies->ht_operation.present)
+ sme_join_rsp->ht_operation = parsed_ies->ht_operation;
+ if (parsed_ies->vht_operation.present)
+ sme_join_rsp->vht_operation = parsed_ies->vht_operation;
+}
/**
* limSendSmeJoinReassocRspAfterResume()
@@ -382,6 +405,7 @@ limSendSmeJoinReassocRsp(tpAniSirGlobal pMac, tANI_U16 msgType,
pSirSmeJoinRsp->bcastSig = pStaDs->ucBcastSig;
pSirSmeJoinRsp->maxRateFlags =
limGetMaxRateFlags(pStaDs, psessionEntry);
+ lim_add_bss_info(pStaDs, pSirSmeJoinRsp);
PELOGE(limLog(pMac, LOG1, FL("maxRateFlags: %x"),
pSirSmeJoinRsp->maxRateFlags);)
}
@@ -2815,10 +2839,8 @@ void limHandleDeleteBssRsp(tpAniSirGlobal pMac,tpSirMsgQ MsgQ)
{
limProcessSmeDelBssRsp(pMac, MsgQ->bodyval,psessionEntry);
}
-
else
limProcessMlmDelBssRsp(pMac,MsgQ,psessionEntry);
-
}
#ifdef WLAN_FEATURE_VOWIFI_11R
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSerDesUtils.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSerDesUtils.c
index 3fb524bf1ea..6e14ba5fe00 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSerDesUtils.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSerDesUtils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -1017,6 +1017,14 @@ limJoinReqSerDes(tpAniSirGlobal pMac, tpSirSmeJoinReq pJoinReq, tANI_U8 *pBuf)
limLog(pMac, LOGE, FL("remaining len %d is too short"), len);
return eSIR_FAILURE;
}
+ // Extract cbMode
+ pJoinReq->force_24ghz_in_ht20 = *pBuf++;
+ len--;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ {
+ limLog(pMac, LOGE, FL("remaining len %d is too short"), len);
+ return eSIR_FAILURE;
+ }
// Extract uapsdPerAcBitmask
pJoinReq->uapsdPerAcBitmask = *pBuf++;
@@ -1640,9 +1648,13 @@ limDisassocCnfSerDes(tpAniSirGlobal pMac, tpSirSmeDisassocCnf pDisassocCnf, tANI
return eSIR_SUCCESS;
} /*** end limDisassocCnfSerDes() ***/
+static inline int CheckRemainingLength(tANI_U16 mLen, tANI_U16 len)
+{
+ if (mLen > (len - sizeof(tANI_U16)))
+ return eSIR_FAILURE;
-
-
+ return eSIR_SUCCESS;
+}
/**---------------------------------------------------------------
\fn limReassocIndSerDes
@@ -1654,11 +1666,15 @@ limDisassocCnfSerDes(tpAniSirGlobal pMac, tpSirSmeDisassocCnf pDisassocCnf, tANI
\param pReassocInd - Pointer to the received tLimMlmReassocInd
\param pBuf - Pointer to serialized buffer
\param psessionEntry - pointer to PE session entry
+\param len - size of tSirSmeReassocInd structure
\
-\return None
+\return tSirRietStatus Indicates whether message is successfully
+\ de-serialized (eSIR_SUCCESS) or
+\ not (eSIR_FAILURE)
------------------------------------------------------------------*/
-void
-limReassocIndSerDes(tpAniSirGlobal pMac, tpLimMlmReassocInd pReassocInd, tANI_U8 *pBuf, tpPESession psessionEntry)
+tSirRetStatus
+limReassocIndSerDes(tpAniSirGlobal pMac, tpLimMlmReassocInd pReassocInd,
+ tANI_U8 *pBuf, tpPESession psessionEntry, tANI_U16 len)
{
tANI_U8 *pLen = pBuf;
tANI_U16 mLen = 0;
@@ -1669,68 +1685,97 @@ limReassocIndSerDes(tpAniSirGlobal pMac, tpLimMlmReassocInd pReassocInd, tANI_U8
mLen = sizeof(tANI_U32);
+ if (CheckRemainingLength(mLen, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
pBuf += sizeof(tANI_U16);
*pBuf++ = psessionEntry->smeSessionId;
mLen += sizeof(tANI_U8);
+ if (CheckRemainingLength(mLen, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
// Fill in peerMacAddr
vos_mem_copy( pBuf, pReassocInd->peerMacAddr, sizeof(tSirMacAddr));
pBuf += sizeof(tSirMacAddr);
mLen += sizeof(tSirMacAddr);
+ if (CheckRemainingLength(mLen, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
// Fill in oldMacAddr
vos_mem_copy( pBuf, pReassocInd->currentApAddr, sizeof(tSirMacAddr));
pBuf += sizeof(tSirMacAddr);
mLen += sizeof(tSirMacAddr);
+ if (CheckRemainingLength(mLen, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
// Fill in aid
limCopyU16(pBuf, pReassocInd->aid);
pBuf += sizeof(tANI_U16);
mLen += sizeof(tANI_U16);
-
+ if (CheckRemainingLength(mLen, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
// Fill in bssId
vos_mem_copy( pBuf, psessionEntry->bssId, sizeof(tSirMacAddr));
pBuf += sizeof(tSirMacAddr);
mLen += sizeof(tSirMacAddr);
+ if (CheckRemainingLength(mLen, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
// Fill in staId
limCopyU16(pBuf, psessionEntry->staId);
pBuf += sizeof(tANI_U16);
mLen += sizeof(tANI_U16);
+ if (CheckRemainingLength(mLen, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
// Fill in authType
limCopyU32(pBuf, pReassocInd->authType);
pBuf += sizeof(tAniAuthType);
mLen += sizeof(tAniAuthType);
+ if (CheckRemainingLength(mLen, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
// Fill in ssId
vos_mem_copy( pBuf, (tANI_U8 *) &(pReassocInd->ssId),
pReassocInd->ssId.length + 1);
pBuf += 1 + pReassocInd->ssId.length;
mLen += pReassocInd->ssId.length + 1;
+ if (CheckRemainingLength(mLen, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
// Fill in rsnIE
limCopyU16(pBuf, pReassocInd->rsnIE.length);
pBuf += sizeof(tANI_U16);
mLen += sizeof(tANI_U16);
+ if (CheckRemainingLength(mLen, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
vos_mem_copy( pBuf, (tANI_U8 *) &(pReassocInd->rsnIE.rsnIEdata),
pReassocInd->rsnIE.length);
pBuf += pReassocInd->rsnIE.length;
mLen += pReassocInd->rsnIE.length;
+ if (CheckRemainingLength(mLen, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
// Fill in addIE
limCopyU16(pBuf, pReassocInd->addIE.length);
pBuf += sizeof(tANI_U16);
mLen += sizeof(tANI_U16);
+ if (CheckRemainingLength(mLen, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
vos_mem_copy( pBuf, (tANI_U8*) &(pReassocInd->addIE.addIEdata),
pReassocInd->addIE.length);
pBuf += pReassocInd->addIE.length;
mLen += pReassocInd->addIE.length;
-
+ if (CheckRemainingLength(mLen, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
limCopyU32(pBuf, pReassocInd->spectrumMgtIndicator);
pBuf += sizeof(tAniBool);
mLen += sizeof(tAniBool);
+ if (CheckRemainingLength(mLen, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
if (pReassocInd->spectrumMgtIndicator == eSIR_TRUE)
{
@@ -1739,10 +1784,14 @@ limReassocIndSerDes(tpAniSirGlobal pMac, tpLimMlmReassocInd pReassocInd, tANI_U8
*pBuf = pReassocInd->powerCap.maxTxPower;
pBuf++;
mLen += sizeof(tSirMacPowerCapInfo);
+ if (CheckRemainingLength(mLen, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
*pBuf = pReassocInd->supportedChannels.numChnl;
pBuf++;
mLen++;
+ if (CheckRemainingLength(mLen, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
vos_mem_copy( pBuf,
(tANI_U8 *) &(pReassocInd->supportedChannels.channelList),
@@ -1750,16 +1799,23 @@ limReassocIndSerDes(tpAniSirGlobal pMac, tpLimMlmReassocInd pReassocInd, tANI_U8
pBuf += pReassocInd->supportedChannels.numChnl;
mLen += pReassocInd->supportedChannels.numChnl;
+ if (CheckRemainingLength(mLen, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
}
limCopyU32(pBuf, pReassocInd->WmmStaInfoPresent);
pBuf += sizeof(tANI_U32);
mLen += sizeof(tANI_U32);
+ if (CheckRemainingLength(mLen, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
// Fill in length of SME_REASSOC_IND message
limCopyU16(pLen, mLen);
PELOG1(limLog(pMac, LOG1, FL("Sending SME_REASSOC_IND length %d bytes:"), mLen);)
PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, mLen);)
+
+ return eSIR_SUCCESS;
} /*** end limReassocIndSerDes() ***/
@@ -1782,12 +1838,15 @@ limReassocIndSerDes(tpAniSirGlobal pMac, tpLimMlmReassocInd pReassocInd, tANI_U8
*
* @param pAuthInd Pointer to tSirSmeAuthInd being sent
* @param pBuf Pointer to serialized buffer
+ * @param len size of tSirSmeAuthInd structure
*
- * @return None
+ * @return tSirRetStatus Indicates whether message is successfully
+ * de-serialized (eSIR_SUCCESS) or
+ * not (eSIR_FAILURE)
*/
-void
-limAuthIndSerDes(tpAniSirGlobal pMac, tpLimMlmAuthInd pAuthInd, tANI_U8 *pBuf)
+tSirRetStatus
+limAuthIndSerDes(tpAniSirGlobal pMac, tpLimMlmAuthInd pAuthInd, tANI_U8 *pBuf, tANI_U16 len)
{
tANI_U8 *pLen = pBuf;
tANI_U16 mLen = 0;
@@ -1797,27 +1856,39 @@ limAuthIndSerDes(tpAniSirGlobal pMac, tpLimMlmAuthInd pAuthInd, tANI_U8 *pBuf)
#endif
mLen = sizeof(tANI_U32);
+ if (CheckRemainingLength(mLen, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
pBuf += sizeof(tANI_U16);
*pBuf++ = pAuthInd->sessionId;
mLen += sizeof(tANI_U8);
+ if (CheckRemainingLength(mLen, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
// BTAMP TODO: Fill in bssId
vos_mem_set(pBuf, sizeof(tSirMacAddr), 0);
pBuf += sizeof(tSirMacAddr);
mLen += sizeof(tSirMacAddr);
+ if (CheckRemainingLength(mLen, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
vos_mem_copy( pBuf, pAuthInd->peerMacAddr, sizeof(tSirMacAddr));
pBuf += sizeof(tSirMacAddr);
mLen += sizeof(tSirMacAddr);
+ if (CheckRemainingLength(mLen, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
limCopyU32(pBuf, pAuthInd->authType);
pBuf += sizeof(tAniAuthType);
mLen += sizeof(tAniAuthType);
-
+ if (CheckRemainingLength(mLen, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
limCopyU16(pLen, mLen);
PELOG1(limLog(pMac, LOG1, FL("Sending SME_AUTH_IND length %d bytes:"), mLen);)
PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, mLen);)
+
+ return eSIR_SUCCESS;
} /*** end limAuthIndSerDes() ***/
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSerDesUtils.h b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSerDesUtils.h
index a43bc131399..29aff5a8519 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSerDesUtils.h
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSerDesUtils.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -50,13 +50,15 @@ tSirRetStatus limStartBssReqSerDes(tpAniSirGlobal, tpSirSmeStartBssReq, tANI_U
tSirRetStatus limStopBssReqSerDes(tpAniSirGlobal, tpSirSmeStopBssReq, tANI_U8 *);
tSirRetStatus limJoinReqSerDes(tpAniSirGlobal, tpSirSmeJoinReq, tANI_U8 *);
void limAssocIndSerDes(tpAniSirGlobal, tpLimMlmAssocInd, tANI_U8 *, tpPESession);
-void limReassocIndSerDes(tpAniSirGlobal, tpLimMlmReassocInd, tANI_U8 *, tpPESession psessionEntry);
+tSirRetStatus limReassocIndSerDes(tpAniSirGlobal, tpLimMlmReassocInd, tANI_U8 *,
+ tpPESession psessionEntry, tANI_U16 len);
tSirRetStatus limAssocCnfSerDes(tpAniSirGlobal, tpSirSmeAssocCnf, tANI_U8 *);
tSirRetStatus limDisassocCnfSerDes(tpAniSirGlobal, tpSirSmeDisassocCnf, tANI_U8 *);
tSirRetStatus limSetContextReqSerDes(tpAniSirGlobal, tpSirSmeSetContextReq, tANI_U8 *);
tSirRetStatus limDisassocReqSerDes(tpAniSirGlobal, tSirSmeDisassocReq *, tANI_U8 *);
tSirRetStatus limDeauthReqSerDes(tpAniSirGlobal, tSirSmeDeauthReq *, tANI_U8 *);
-void limAuthIndSerDes(tpAniSirGlobal, tpLimMlmAuthInd, tANI_U8 *);
+tSirRetStatus limAuthIndSerDes(tpAniSirGlobal, tpLimMlmAuthInd, tANI_U8 *,
+ tANI_U16 len);
void limStatSerDes(tpAniSirGlobal, tpAniStaStatStruct, tANI_U8 *);
void limGetSessionInfo(tpAniSirGlobal pMac, tANI_U8 *, tANI_U8 *, tANI_U16 *);
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSession.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSession.c
index 58b757186d7..23c53bd616d 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSession.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSession.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2014, 2016-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -236,6 +236,20 @@ tpPESession peFindSessionByBssid(tpAniSirGlobal pMac, tANI_U8* bssid, tANI_
}
+tANI_S8 limGetInfraSessionId(tpAniSirGlobal pMac)
+{
+ tANI_U8 i;
+ for (i = 0; i < pMac->lim.maxBssId; i++)
+ {
+ if ((pMac->lim.gpSession[i].valid) &&
+ (pMac->lim.gpSession[i].limSystemRole == eLIM_STA_ROLE))
+ {
+ return i;
+ }
+ }
+ limLog(pMac, LOG4, FL("Session lookup fails for infra mode"));
+ return -1;
+}
/*--------------------------------------------------------------------------
\brief peFindSessionByBssIdx() - looks up the PE session given the bssIdx.
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limTimerUtils.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limTimerUtils.c
index 02372713712..1e474218b12 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limTimerUtils.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limTimerUtils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -64,6 +64,10 @@
convert ACTIVE DFS channel to DFS channels */
#define ACTIVE_TO_PASSIVE_CONVERISON_TIMEOUT 1000
+#ifdef WLAN_FEATURE_LFR_MBB
+#define PREAUTH_REASSOC_TIMEOUT 500
+#endif
+
/**
* limCreateTimers()
*
@@ -624,6 +628,34 @@ limCreateTimers(tpAniSirGlobal pMac)
}
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+ cfgValue = PREAUTH_REASSOC_TIMEOUT;
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+
+ if (tx_timer_create(&pMac->lim.limTimers.glim_pre_auth_mbb_rsp_timer,
+ "PREAUTH MBB RSP TIMEOUT",
+ limTimerHandler, SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT,
+ cfgValue, 0,
+ TX_NO_ACTIVATE) != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("could not create PREAUTH_MBB_RSP timer"));
+ goto err_timer;
+ }
+
+ cfgValue = PREAUTH_REASSOC_TIMEOUT;
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+
+ if (tx_timer_create(&pMac->lim.limTimers.glim_reassoc_mbb_rsp_timer,
+ "REASSOC MBB RSP TIMEOUT",
+ limTimerHandler, SIR_LIM_REASSOC_MBB_RSP_TIMEOUT,
+ cfgValue, 0,
+ TX_NO_ACTIVATE) != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("could not create REASSOC_MBB_RSP timer"));
+ goto err_timer;
+ }
+#endif
+
#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD)
cfgValue = 5000;
cfgValue = SYS_MS_TO_TICKS(cfgValue);
@@ -712,6 +744,10 @@ limCreateTimers(tpAniSirGlobal pMac)
tx_timer_delete(&pMac->lim.limTimers.gLimEseTsmTimer);
#endif /* FEATURE_WLAN_ESE && !FEATURE_WLAN_ESE_UPLOAD */
tx_timer_delete(&pMac->lim.limTimers.gLimFTPreAuthRspTimer);
+#ifdef WLAN_FEATURE_LFR_MBB
+ tx_timer_delete(&pMac->lim.limTimers.glim_pre_auth_mbb_rsp_timer);
+ tx_timer_delete(&pMac->lim.limTimers.glim_reassoc_mbb_rsp_timer);
+#endif
tx_timer_delete(&pMac->lim.limTimers.gLimUpdateOlbcCacheTimer);
while(((tANI_S32)--i) >= 0)
{
@@ -1730,6 +1766,30 @@ limDeactivateAndChangeTimer(tpAniSirGlobal pMac, tANI_U32 timerId)
}
break;
#endif
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ case eLIM_PREAUTH_MBB_RSP_TIMER:
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE,
+ NO_SESSION, eLIM_PREAUTH_MBB_RSP_TIMER));
+ if (tx_timer_deactivate(&pMac->lim.limTimers.
+ glim_pre_auth_mbb_rsp_timer) != TX_SUCCESS) {
+ limLog(pMac, LOGP,
+ FL("Unable to deactivate preauth response mbb timer"));
+ return;
+ }
+ break;
+ case eLIM_REASSOC_MBB_RSP_TIMER:
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE,
+ NO_SESSION, eLIM_REASSOC_MBB_RSP_TIMER));
+ if (tx_timer_deactivate(&pMac->lim.limTimers.
+ glim_reassoc_mbb_rsp_timer) != TX_SUCCESS) {
+ limLog(pMac, LOGP,
+ FL("Unable to deactivate reassoc response mbb timer"));
+ return;
+ }
+ break;
+#endif
+
#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD)
case eLIM_TSM_TIMER:
if (tx_timer_deactivate(&pMac->lim.limTimers.gLimEseTsmTimer)
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limTimerUtils.h b/drivers/staging/prima/CORE/MAC/src/pe/lim/limTimerUtils.h
index 19061826dc8..eba64ac72a7 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limTimerUtils.h
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limTimerUtils.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2015, 2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -77,7 +77,11 @@ enum
eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER,
eLIM_INSERT_SINGLESHOT_NOA_TIMER,
eLIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE,
- eLIM_AUTH_RETRY_TIMER
+ eLIM_AUTH_RETRY_TIMER,
+#ifdef WLAN_FEATURE_LFR_MBB
+ eLIM_PREAUTH_MBB_RSP_TIMER,
+ eLIM_REASSOC_MBB_RSP_TIMER
+#endif
};
#define LIM_DISASSOC_DEAUTH_ACK_TIMEOUT 500
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limTrace.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limTrace.c
index 662670bac52..d33a33d93c5 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limTrace.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limTrace.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2015, 2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -92,6 +92,10 @@ static tANI_U8* __limTraceGetTimerString( tANI_U16 timerId )
CASE_RETURN_STRING(eLIM_INSERT_SINGLESHOT_NOA_TIMER);
CASE_RETURN_STRING(eLIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE);
CASE_RETURN_STRING(eLIM_AUTH_RETRY_TIMER);
+#ifdef WLAN_FEATURE_LFR_MBB
+ CASE_RETURN_STRING(eLIM_PREAUTH_MBB_RSP_TIMER);
+ CASE_RETURN_STRING(eLIM_REASSOC_MBB_RSP_TIMER);
+#endif
default:
return( "UNKNOWN" );
break;
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limTypes.h b/drivers/staging/prima/CORE/MAC/src/pe/lim/limTypes.h
index a375494faa0..5fd9ce0702e 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limTypes.h
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limTypes.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -694,14 +694,16 @@ void limSendAddtsReqActionFrame(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
void limSendAddtsRspActionFrame(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
tANI_U16 statusCode, tSirAddtsReqInfo *addts, tSirMacScheduleIE *pSchedule,tpPESession);
-void limSendAssocRspMgmtFrame(tpAniSirGlobal, tANI_U16, tANI_U16, tSirMacAddr, tANI_U8, tpDphHashNode pSta,tpPESession);
+void limSendAssocRspMgmtFrame(tpAniSirGlobal, tANI_U16, tANI_U16, tSirMacAddr,
+ tANI_U8, tpDphHashNode pSta,tpPESession,
+ assoc_rsp_tx_context *tx_complete_context);
void limSendNullDataFrame(tpAniSirGlobal, tpDphHashNode);
void limSendDisassocMgmtFrame(tpAniSirGlobal, tANI_U16, tSirMacAddr, tpPESession, tANI_BOOLEAN waitForAck);
void limSendDeauthMgmtFrame(tpAniSirGlobal, tANI_U16, tSirMacAddr, tpPESession, tANI_BOOLEAN waitForAck);
void limSendSmeDisassocDeauthNtf( tpAniSirGlobal pMac,
eHalStatus status, tANI_U32 *pCtx );
-
+void limDoSendAuthMgmtFrame(tpAniSirGlobal, tpPESession);
void limContinueChannelScan(tpAniSirGlobal);
tSirResultCodes limMlmAddBss(tpAniSirGlobal, tLimMlmStartReq *,tpPESession psessionEntry);
@@ -1072,5 +1074,15 @@ tSirRetStatus limProcessSmeSetTdls2040BSSCoexReq(tpAniSirGlobal pMac,
tANI_U32 *pMsgBuf);
tSirRetStatus limProcessSmeDelAllTdlsPeers(tpAniSirGlobal pMac,
tANI_U32 *pMsgBuf);
+
+tSirRetStatus lim_process_sme_cap_tsf_req(tpAniSirGlobal pMac,
+ tANI_U32 *pMsgBuf);
+
+tSirRetStatus lim_process_sme_get_tsf_req(tpAniSirGlobal pMac,
+ tANI_U32 *pMsgBuf);
+
+tSirRetStatus lim_process_sme_del_ba_ses_req(tpAniSirGlobal pMac,
+ tANI_U32 *pMsgBuf);
+
#endif /* __LIM_TYPES_H */
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limUtils.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limUtils.c
index f8c315a8cf0..ec59de06dd2 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limUtils.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limUtils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -59,6 +59,9 @@
#ifdef WLAN_FEATURE_11W
#include "wniCfg.h"
#endif
+#ifdef SAP_AUTH_OFFLOAD
+#include "limAssocUtils.h"
+#endif
/* Static global used to mark situations where pMac->lim.gLimTriggerBackgroundScanDuringQuietBss is SET
* and limTriggerBackgroundScanDuringQuietBss() returned failure. In this case, we will stop data
@@ -645,6 +648,13 @@ char *limMsgStr(tANI_U32 msgType)
return "SIR_LIM_FT_PREAUTH_RSP_TIMEOUT";
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+ case SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT:
+ return "SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT";
+ case SIR_LIM_REASSOC_MBB_RSP_TIMEOUT:
+ return "SIR_LIM_REASSOC_MBB_RSP_TIMEOUT";
+#endif
+
case SIR_HAL_APP_SETUP_NTF:
return "SIR_HAL_APP_SETUP_NTF";
case SIR_HAL_INITIAL_CAL_FAILED_NTF:
@@ -5241,6 +5251,13 @@ void limUpdateStaRunTimeHTSwitchChnlParams( tpAniSirGlobal pMac,
if( !limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, psessionEntry ))
return;
+ if ((RF_CHAN_14 >= psessionEntry->currentOperChannel) &&
+ psessionEntry->force_24ghz_in_ht20) {
+ limLog(pMac, LOG1,
+ FL("force_24_gh_in_ht20 is set and channel is 2.4 Ghz"));
+ return;
+ }
+
#if !defined WLAN_FEATURE_VOWIFI
if(wlan_cfgGetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, &localPwrConstraint) != eSIR_SUCCESS) {
limLog( pMac, LOGP, FL( "Unable to get Local Power Constraint from cfg" ));
@@ -8524,6 +8541,84 @@ eHalStatus limTxBdComplete(tpAniSirGlobal pMac, void *pData)
return eHAL_STATUS_SUCCESS;
}
+eHalStatus limAssocRspTxCompleteCnf(tpAniSirGlobal pMac, void *pData)
+{
+ tpSirTxBdStatus pTxBdStatus;
+ tpDphHashNode pStaDs;
+ tpPESession psessionEntry;
+ VOS_STATUS vosStatus;
+ vos_list_node_t *pNode= NULL, *pNext = NULL;
+ assoc_rsp_tx_context *tmp_tx_context = NULL;
+
+ if (!pData)
+ {
+ limLog(pMac, LOGE, FL("pData is NULL"));
+ return eHAL_STATUS_FAILURE;
+ }
+
+ pTxBdStatus = (tpSirTxBdStatus) pData;
+
+ limLog(pMac, LOG1, FL("txBdToken %u, txBdStatus %u"),
+ pTxBdStatus->txBdToken, pTxBdStatus->txCompleteStatus);
+
+ vos_list_peek_front(&pMac->assoc_rsp_completion_list,
+ &pNode);
+
+ while(pNode)
+ {
+ tmp_tx_context = container_of(pNode, assoc_rsp_tx_context, node);
+ if (tmp_tx_context->txBdToken != pTxBdStatus->txBdToken)
+ {
+ limLog(pMac, LOG1, FL("expecting txBdToken %u, got txBdToken %u"),
+ tmp_tx_context->txBdToken, pTxBdStatus->txBdToken);
+
+ vosStatus = vos_list_peek_next (
+ &pMac->assoc_rsp_completion_list,
+ pNode, &pNext );
+ pNode = pNext;
+ pNext = NULL;
+ }
+ else
+ {
+ limLog(pMac, LOG1, FL("expecting txBdToken %u, got txBdToken %u"),
+ tmp_tx_context->txBdToken, pTxBdStatus->txBdToken);
+ break;
+ }
+ }
+
+ if (!tmp_tx_context) {
+ limLog(pMac, LOGE, FL("context is NULL"));
+ return eHAL_STATUS_SUCCESS;
+ }
+ psessionEntry = peFindSessionBySessionId(pMac, tmp_tx_context->psessionID);
+ if (!psessionEntry) {
+ limLog(pMac, LOGE, FL("failed to get psession pointer"));
+ vos_list_remove_node(&pMac->assoc_rsp_completion_list,
+ pNode);
+ vos_mem_free(tmp_tx_context);
+ return eHAL_STATUS_SUCCESS;
+ }
+ pStaDs = dphGetHashEntry(pMac, tmp_tx_context->staId,
+ &psessionEntry->dph.dphHashTable);
+ if (pStaDs == NULL)
+ {
+ limLog(pMac, LOGW,
+ FL("STA context not found"));
+ vos_list_remove_node(&pMac->assoc_rsp_completion_list,
+ pNode);
+ vos_mem_free(tmp_tx_context);
+
+ return eHAL_STATUS_SUCCESS;
+ }
+
+ /* Receive path cleanup */
+ limCleanupRxPath(pMac, pStaDs, psessionEntry);
+ vos_list_remove_node(&pMac->assoc_rsp_completion_list,
+ pNode);
+ vos_mem_free(tmp_tx_context);
+
+ return eHAL_STATUS_SUCCESS;
+}
/**
* lim_is_robust_mgmt_action_frame() - Check if action catagory is
* robust action frame
@@ -8617,3 +8712,542 @@ void lim_update_caps_info_for_bss(tpAniSirGlobal mac_ctx,
limLog(mac_ctx, LOG1, FL("Clearing Immed Blk Ack:no AP support"));
}
}
+#ifdef SAP_AUTH_OFFLOAD
+/**
+ * _sap_offload_parse_assoc_req - Parse assoc request and store it.
+ *
+ * @pmac: mac context
+ * @assoc_req: Assoc request
+ * @add_sta_req: Add Sta request
+ *
+ * This function process recieved add sta message and store it as
+ * sta ds entry. This function will add this sta entry to DPH as well.
+ *
+ * Return: DPH hash node
+ */
+static tpDphHashNode
+_sap_offload_parse_assoc_req(tpAniSirGlobal pmac,
+ tpSirAssocReq assoc_req,
+ tSapOfldAddStaIndMsg *add_sta_req)
+{
+ tpSirMacAssocReqFrame mac_assoc_req = NULL;
+ tpSirAssocReq temp_assoc_req;
+ tSirRetStatus status;
+ tpDphHashNode sta_ds = NULL;
+ uint8_t *frame_body = NULL;
+
+ tpPESession session_entry = limIsApSessionActive(pmac);
+
+ if (session_entry == NULL)
+ {
+ PELOGE(limLog(pmac, LOGE, FL(" Session not found"));)
+ return NULL;
+ }
+
+ /* Update Attribute and Remove IE for
+ * Software AP Authentication Offload
+ */
+ frame_body = (tANI_U8 *)add_sta_req->bufp;
+ mac_assoc_req = (tpSirMacAssocReqFrame)frame_body;
+ mac_assoc_req->capabilityInfo.privacy = 0;
+
+ status = sirConvertAssocReqFrame2Struct(pmac,
+ frame_body,
+ add_sta_req->data_len,
+ assoc_req);
+ if (status != eSIR_SUCCESS)
+ {
+ limLog(pmac, LOGW, FL("sap_offload_add_sta_req parse error"));
+ goto error;
+ }
+ /* For software AP Auth Offload feature
+ * Host will take it as none security station
+ * Force change to none security
+ */
+ assoc_req->rsnPresent = 0;
+ assoc_req->wpaPresent = 0;
+
+ sta_ds = dphAddHashEntry(pmac,
+ add_sta_req->peer_macaddr,
+ add_sta_req->assoc_id,
+ &session_entry->dph.dphHashTable);
+ if (sta_ds == NULL)
+ {
+ /* Could not add hash table entry at DPH */
+ limLog(pmac, LOGE,
+ FL("could not add hash entry at DPH for aid=%d, MacAddr:"
+ MAC_ADDRESS_STR),
+ add_sta_req->assoc_id,MAC_ADDR_ARRAY(add_sta_req->peer_macaddr));
+ goto error;
+ }
+
+ if (session_entry->parsedAssocReq != NULL)
+ {
+ temp_assoc_req = session_entry->parsedAssocReq[sta_ds->assocId];
+ if (temp_assoc_req != NULL)
+ {
+ if (temp_assoc_req->assocReqFrame)
+ {
+ vos_mem_free(temp_assoc_req->assocReqFrame);
+ temp_assoc_req->assocReqFrame = NULL;
+ temp_assoc_req->assocReqFrameLength = 0;
+ }
+ vos_mem_free(temp_assoc_req);
+ temp_assoc_req = NULL;
+ }
+ session_entry->parsedAssocReq[sta_ds->assocId] = assoc_req;
+ }
+error:
+ return sta_ds;
+}
+
+/**
+ * _sap_offload_parse_sta_capability - Parse sta caps from assoc request
+ *
+ * @sta_ds: STA state node
+ * @assoc_req: Assoc request
+ * @add_sta_req: Add Sta request
+ *
+ * This function process recieved add sta message and store station's caps
+ * in station ds entry.
+ *
+ * Return: none
+ */
+static void
+_sap_offload_parse_sta_capability(tpDphHashNode sta_ds,
+ tpSirAssocReq assoc_req,
+ tSapOfldAddStaIndMsg *add_sta_req)
+
+{
+
+ sta_ds->mlmStaContext.htCapability = assoc_req->HTCaps.present;
+#ifdef WLAN_FEATURE_11AC
+ sta_ds->mlmStaContext.vhtCapability = assoc_req->VHTCaps.present;
+#endif
+ sta_ds->qos.addtsPresent = (assoc_req->addtsPresent==0) ? false : true;
+ sta_ds->qos.addts = assoc_req->addtsReq;
+ sta_ds->qos.capability = assoc_req->qosCapability;
+ sta_ds->versionPresent = 0;
+ /* short slot and short preamble should be
+ * updated before doing limaddsta
+ */
+ sta_ds->shortPreambleEnabled =
+ (tANI_U8)assoc_req->capabilityInfo.shortPreamble;
+ sta_ds->shortSlotTimeEnabled =
+ (tANI_U8)assoc_req->capabilityInfo.shortSlotTime;
+
+ sta_ds->valid = 0;
+ /* The Auth Type of Software AP Authentication Offload
+ * is always Open System is host side
+ */
+ sta_ds->mlmStaContext.authType = eSIR_OPEN_SYSTEM;
+ sta_ds->staType = STA_ENTRY_PEER;
+
+ /* Assoc Response frame to requesting STA */
+ sta_ds->mlmStaContext.subType = 0;
+
+ sta_ds->mlmStaContext.listenInterval = assoc_req->listenInterval;
+ sta_ds->mlmStaContext.capabilityInfo = assoc_req->capabilityInfo;
+
+ /* The following count will be used to knock-off the station
+ * if it doesn't come back to receive the buffered data.
+ * The AP will wait for numTimSent number of beacons after
+ * sending TIM information for the station, before assuming that
+ * the station is no more associated and disassociates it
+ */
+
+ /* timWaitCount is used by PMM for monitoring the STA's in PS for LINK*/
+ sta_ds->timWaitCount =
+ (tANI_U8)GET_TIM_WAIT_COUNT(assoc_req->listenInterval);
+
+ /* Initialise the Current successful
+ * MPDU's tranfered to this STA count as 0
+ */
+ sta_ds->curTxMpduCnt = 0;
+}
+
+/**
+ * _sap_offload_parse_sta_vht - Parse sta's HT/VHT caps from assoc request
+ *
+ * @pmac: mac context
+ * @sta_ds: STA state node
+ * @assoc_req: Assoc request
+ *
+ * This function process recieved add sta message and store station's HT and
+ * and VHT caps and store them in station ds entry.
+ *
+ * Return: tSirRetStatus
+ */
+static tSirRetStatus
+_sap_offload_parse_sta_vht(tpAniSirGlobal pmac,
+ tpDphHashNode sta_ds,
+ tpSirAssocReq assoc_req)
+{
+ tpPESession session_entry = limIsApSessionActive(pmac);
+
+ if (IS_DOT11_MODE_HT(session_entry->dot11mode) &&
+ assoc_req->HTCaps.present && assoc_req->wmeInfoPresent)
+ {
+ sta_ds->htGreenfield = (tANI_U8)assoc_req->HTCaps.greenField;
+ sta_ds->htAMpduDensity = assoc_req->HTCaps.mpduDensity;
+ sta_ds->htDsssCckRate40MHzSupport =
+ (tANI_U8)assoc_req->HTCaps.dsssCckMode40MHz;
+ sta_ds->htLsigTXOPProtection =
+ (tANI_U8)assoc_req->HTCaps.lsigTXOPProtection;
+ sta_ds->htMaxAmsduLength =
+ (tANI_U8)assoc_req->HTCaps.maximalAMSDUsize;
+ sta_ds->htMaxRxAMpduFactor = assoc_req->HTCaps.maxRxAMPDUFactor;
+ sta_ds->htMIMOPSState = assoc_req->HTCaps.mimoPowerSave;
+ sta_ds->htShortGI20Mhz = (tANI_U8)assoc_req->HTCaps.shortGI20MHz;
+ sta_ds->htShortGI40Mhz = (tANI_U8)assoc_req->HTCaps.shortGI40MHz;
+ sta_ds->htSupportedChannelWidthSet =
+ (tANI_U8)assoc_req->HTCaps.supportedChannelWidthSet;
+ /* peer just follows AP; so when we are softAP/GO,
+ * we just store our session entry's secondary channel offset here
+ * in peer INFRA STA. However, if peer's 40MHz channel width support
+ * is disabled then secondary channel will be zero
+ */
+ sta_ds->htSecondaryChannelOffset =
+ (sta_ds->htSupportedChannelWidthSet) ?
+ session_entry->htSecondaryChannelOffset : 0;
+#ifdef WLAN_FEATURE_11AC
+ if (assoc_req->operMode.present)
+ {
+ sta_ds->vhtSupportedChannelWidthSet =
+ (tANI_U8)((assoc_req->operMode.chanWidth ==
+ eHT_CHANNEL_WIDTH_80MHZ) ?
+ WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ :
+ WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ);
+ sta_ds->htSupportedChannelWidthSet =
+ (tANI_U8)(assoc_req->operMode.chanWidth ?
+ eHT_CHANNEL_WIDTH_40MHZ : eHT_CHANNEL_WIDTH_20MHZ);
+ }
+ else if (assoc_req->VHTCaps.present)
+ {
+ /* Check if STA has enabled it's channel bonding mode.
+ * If channel bonding mode is enabled, we decide based on
+ * SAP's current configuration else, we set it to VHT20.
+ */
+ sta_ds->vhtSupportedChannelWidthSet =
+ (tANI_U8)((sta_ds->htSupportedChannelWidthSet ==
+ eHT_CHANNEL_WIDTH_20MHZ) ?
+ WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ :
+ session_entry->vhtTxChannelWidthSet );
+ sta_ds->htMaxRxAMpduFactor = assoc_req->VHTCaps.maxAMPDULenExp;
+ }
+
+ /* Lesser among the AP and STA bandwidth of operation. */
+ sta_ds->htSupportedChannelWidthSet =
+ (sta_ds->htSupportedChannelWidthSet <
+ session_entry->htSupportedChannelWidthSet) ?
+ sta_ds->htSupportedChannelWidthSet :
+ session_entry->htSupportedChannelWidthSet ;
+#endif
+ sta_ds->baPolicyFlag = 0xFF;
+ sta_ds->htLdpcCapable = (tANI_U8)assoc_req->HTCaps.advCodingCap;
+ }
+
+ if (assoc_req->VHTCaps.present && assoc_req->wmeInfoPresent)
+ sta_ds->vhtLdpcCapable = (tANI_U8)assoc_req->VHTCaps.ldpcCodingCap;
+
+ if (!assoc_req->wmeInfoPresent)
+ {
+ sta_ds->mlmStaContext.htCapability = 0;
+#ifdef WLAN_FEATURE_11AC
+ sta_ds->mlmStaContext.vhtCapability = 0;
+#endif
+ }
+#ifdef WLAN_FEATURE_11AC
+ if (limPopulateMatchingRateSet(pmac,
+ sta_ds,
+ &(assoc_req->supportedRates),
+ &(assoc_req->extendedRates),
+ assoc_req->HTCaps.supportedMCSSet,
+ &(assoc_req->propIEinfo.propRates),
+ session_entry , &assoc_req->VHTCaps)
+ != eSIR_SUCCESS)
+ {
+#else
+ if (limPopulateMatchingRateSet(pmac,
+ sta_ds,
+ &(assoc_req->supportedRates),
+ &(assoc_req->extendedRates),
+ assoc_req->HTCaps.supportedMCSSet,
+ &(assoc_req->propIEinfo.propRates),
+ session_entry) != eSIR_SUCCESS)
+ {
+#endif
+ limLog(pmac, LOGE,
+ FL("Rate set mismatched for aid=%d, MacAddr: "
+ MAC_ADDRESS_STR),
+ sta_ds->assocId, MAC_ADDR_ARRAY(sta_ds->staAddr));
+ goto error;
+ }
+ return eSIR_SUCCESS;
+error:
+ return eSIR_FAILURE;
+}
+
+/**
+ * _sap_offload_parse_sta_qos - Parse sta's QOS caps from assoc request
+ *
+ * @pmac: mac context
+ * @sta_ds: STA state node
+ * @assoc_req: Assoc request
+ *
+ * This function process recieved add sta message and store station's QOS
+ * store them in station ds entry.
+ *
+ * Return: none
+ */
+static void
+ _sap_offload_parse_sta_qos(tpAniSirGlobal pmac,
+ tpDphHashNode sta_ds,
+ tpSirAssocReq assoc_req)
+{
+ tHalBitVal qos_mode;
+ tHalBitVal wsm_mode, wme_mode;
+ tpPESession session_entry = limIsApSessionActive(pmac);
+
+ limGetQosMode(session_entry, &qos_mode);
+ sta_ds->qosMode = eANI_BOOLEAN_FALSE;
+ sta_ds->lleEnabled = eANI_BOOLEAN_FALSE;
+
+ if (assoc_req->capabilityInfo.qos && (qos_mode == eHAL_SET))
+ {
+ sta_ds->lleEnabled = eANI_BOOLEAN_TRUE;
+ sta_ds->qosMode = eANI_BOOLEAN_TRUE;
+ }
+
+ sta_ds->wmeEnabled = eANI_BOOLEAN_FALSE;
+ sta_ds->wsmEnabled = eANI_BOOLEAN_FALSE;
+ limGetWmeMode(session_entry, &wme_mode);
+ if ((!sta_ds->lleEnabled) && assoc_req->wmeInfoPresent &&
+ (wme_mode == eHAL_SET))
+ {
+ sta_ds->wmeEnabled = eANI_BOOLEAN_TRUE;
+ sta_ds->qosMode = eANI_BOOLEAN_TRUE;
+ limGetWsmMode(session_entry, &wsm_mode);
+ /* WMM_APSD - WMM_SA related processing should be
+ * separate; WMM_SA and WMM_APSD can coexist
+ */
+ if (assoc_req->WMMInfoStation.present)
+ {
+ /* check whether AP supports or not */
+ if ((session_entry->limSystemRole == eLIM_AP_ROLE)
+ && (session_entry->apUapsdEnable == 0) &&
+ (assoc_req->WMMInfoStation.acbe_uapsd
+ || assoc_req->WMMInfoStation.acbk_uapsd
+ || assoc_req->WMMInfoStation.acvo_uapsd
+ || assoc_req->WMMInfoStation.acvi_uapsd))
+ {
+ /*
+ * Received Re/Association Request from
+ * STA when UPASD is not supported
+ */
+ limLog( pmac, LOGE, FL( "AP do not support UAPSD so reply "
+ "to STA accordingly" ));
+ /* update UAPSD and send it to LIM to add STA */
+ sta_ds->qos.capability.qosInfo.acbe_uapsd = 0;
+ sta_ds->qos.capability.qosInfo.acbk_uapsd = 0;
+ sta_ds->qos.capability.qosInfo.acvo_uapsd = 0;
+ sta_ds->qos.capability.qosInfo.acvi_uapsd = 0;
+ sta_ds->qos.capability.qosInfo.maxSpLen = 0;
+ }
+ else
+ {
+ /* update UAPSD and send it to LIM to add STA */
+ sta_ds->qos.capability.qosInfo.acbe_uapsd =
+ assoc_req->WMMInfoStation.acbe_uapsd;
+ sta_ds->qos.capability.qosInfo.acbk_uapsd =
+ assoc_req->WMMInfoStation.acbk_uapsd;
+ sta_ds->qos.capability.qosInfo.acvo_uapsd =
+ assoc_req->WMMInfoStation.acvo_uapsd;
+ sta_ds->qos.capability.qosInfo.acvi_uapsd =
+ assoc_req->WMMInfoStation.acvi_uapsd;
+ sta_ds->qos.capability.qosInfo.maxSpLen =
+ assoc_req->WMMInfoStation.max_sp_length;
+ }
+ }
+ if (assoc_req->wsmCapablePresent && (wsm_mode == eHAL_SET))
+ sta_ds->wsmEnabled = eANI_BOOLEAN_TRUE;
+ }
+}
+
+/**
+ * lim_sap_offload_add_sta - Parse Add sta request from firmware
+ *
+ * @pmac: mac context
+ * @lim_msgq: Add Sta indication buffer
+ *
+ * This function will recieve buffer from firmware. This buffer will store
+ * information about connected client. driver will process this buffer and
+ * will register this client with driver. Driver will call limAddSta
+ *
+ * Return: none
+ */
+void lim_sap_offload_add_sta(tpAniSirGlobal pmac,
+ tSapOfldAddStaIndMsg *lim_msgq)
+{
+ tpSirAssocReq assoc_req = NULL;
+ tpDphHashNode sta_ds = NULL;
+
+ tSapOfldAddStaIndMsg *add_sta_req = NULL;
+ tpPESession session_entry = limIsApSessionActive(pmac);
+
+ if (session_entry == NULL)
+ {
+ PELOGE(limLog(pmac, LOGE, FL(" Session not found"));)
+ return;
+ }
+ add_sta_req = lim_msgq;
+ assoc_req = vos_mem_malloc(sizeof(*assoc_req));
+ if (NULL == assoc_req) {
+ limLog(pmac, LOGP, FL("Allocate Memory failed in AssocReq"));
+ return;
+ }
+ vos_mem_set(assoc_req , sizeof(*assoc_req), 0);
+
+ /* parse Assoc req frame for station information */
+ sta_ds = _sap_offload_parse_assoc_req(pmac, assoc_req, add_sta_req);
+ if (sta_ds == NULL)
+ {
+ PELOGE(limLog(pmac, LOGE, FL("could not add hash entry for"));)
+ limPrintMacAddr(pmac, add_sta_req->peer_macaddr, LOGE);
+ vos_mem_free(assoc_req);
+ goto error;
+ }
+
+ /* Parse Station Capability */
+ _sap_offload_parse_sta_capability(sta_ds, assoc_req, add_sta_req);
+
+ /* Parse Station HT/VHT information */
+ if (_sap_offload_parse_sta_vht(pmac, sta_ds, assoc_req)
+ == eSIR_FAILURE)
+ {
+ PELOGE(limLog(pmac, LOGE, FL("mismatch ht/vht information for "));)
+ limPrintMacAddr(pmac, add_sta_req->peer_macaddr, LOGE);
+ vos_mem_free(assoc_req);
+ goto error;
+
+ }
+
+ /* Parse Station QOS information */
+ _sap_offload_parse_sta_qos(pmac, sta_ds, assoc_req);
+
+ session_entry->parsedAssocReq[sta_ds->assocId] = assoc_req;
+ sta_ds->staIndex = add_sta_req->staIdx;
+ sta_ds->dpuIndex = add_sta_req->dpuIndex;
+ sta_ds->bcastDpuIndex = add_sta_req->bcastDpuIndex;
+ sta_ds->bcastMgmtDpuIdx = add_sta_req->bcastMgmtDpuIdx;
+ sta_ds->ucUcastSig = add_sta_req->ucUcastSig;
+ sta_ds->ucBcastSig = add_sta_req->ucBcastSig;
+ sta_ds->ucMgmtSig = add_sta_req->ucMgmtSig;
+ sta_ds->bssId = add_sta_req->bssIdx;
+
+ limLog(pmac, LOG1, FL("StaIndex %d BssIDx %d dpuIndex %d bcastDpuIndex %d bcastMgmtDpuIdx %d ucUcastSig %d ucBcastSig %d ucMgmtSig %d AssocId %d"),
+ sta_ds->staIndex,
+ sta_ds->bssId,
+ sta_ds->dpuIndex,
+ sta_ds->bcastDpuIndex,
+ sta_ds->bcastMgmtDpuIdx,
+ sta_ds->ucUcastSig,
+ sta_ds->ucBcastSig,
+ sta_ds->ucMgmtSig,
+ sta_ds->assocId);
+
+ if (limAddSta(pmac, sta_ds, false, session_entry) != eSIR_SUCCESS) {
+ limLog(pmac, LOGE, FL("could not Add STA with assocId=%d"),
+ sta_ds->assocId);
+ }
+
+error:
+ return;
+}
+
+/**
+ * lim_sap_offload_del_sta - Parse Del sta request from firmware
+ *
+ * @pmac: mac context
+ * @lim_msgq: Del Sta indication buffer
+ *
+ * This function will recieve buffer from firmware. This buffer will
+ * have information about clinet to remove with reason code.
+ * This function will call limSendSmeDisassocInd to do cleanup
+ * for station entry
+ *
+ * Return: none
+ */
+void
+lim_sap_offload_del_sta(tpAniSirGlobal pmac, tSapOfldDelStaIndMsg *lim_msgq)
+{
+ tSapOfldDelStaIndMsg *del_sta_req = NULL;
+ tpDphHashNode sta_ds = NULL;
+ tANI_U16 assoc_id = 0;
+ tpPESession psession_entry = limIsApSessionActive(pmac);
+
+ if (psession_entry == NULL)
+ {
+ PELOGE(limLog(pmac, LOGE, FL(" Session not found"));)
+ goto error;
+ }
+
+ del_sta_req = lim_msgq;
+ sta_ds = dphLookupHashEntry(pmac,
+ del_sta_req->peer_macaddr,
+ &assoc_id,
+ &psession_entry->dph.dphHashTable);
+ if (sta_ds == NULL)
+ {
+ /*
+ * Disassociating STA is not associated.
+ * Log error
+ */
+ PELOGE(limLog(pmac, LOGE,
+ FL("received del sta event that sta not exist in table "
+ "reasonCode=%d, addr "MAC_ADDRESS_STR),
+ del_sta_req->reason,
+ MAC_ADDR_ARRAY(del_sta_req->peer_macaddr));)
+ goto error;
+ }
+
+ if (assoc_id != (tANI_U16)del_sta_req->assoc_id)
+ {
+ /*
+ * Associate Id mismatch
+ * Log error
+ */
+ PELOGE(limLog(pmac, LOGE,
+ FL("received del sta event that sta assoc Id mismatch"));)
+ goto error;
+ }
+
+ sta_ds->mlmStaContext.cleanupTrigger = eLIM_PEER_ENTITY_DISASSOC;
+ sta_ds->mlmStaContext.disassocReason =
+ (tSirMacReasonCodes) del_sta_req->reason;
+
+ limSendSmeDisassocInd(pmac, sta_ds, psession_entry);
+
+error:
+ return;
+}
+#endif /* SAP_AUTH_OFFLOAD */
+
+int peFindBssIdxFromSmeSessionId(tpAniSirGlobal pMac, tANI_U8 sme_sessionId)
+{
+ tANI_U8 i;
+ tpPESession psessionEntry = NULL;
+
+ for(i =0; i < pMac->lim.maxBssId; i++)
+ {
+ /* If BSSID matches return corresponding tables address*/
+ if( (pMac->lim.gpSession[i].valid) && (pMac->lim.gpSession[i].smeSessionId == sme_sessionId))
+ {
+ psessionEntry = (&pMac->lim.gpSession[i]);
+ return psessionEntry->bssIdx;
+ }
+ }
+
+ limLog(pMac, LOG4, FL("Session lookup fails for sme_sessionId: "));
+ return(0xFF);
+}
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limUtils.h b/drivers/staging/prima/CORE/MAC/src/pe/lim/limUtils.h
index 622774aceb5..8083629c600 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limUtils.h
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limUtils.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -573,9 +573,15 @@ extern tANI_U32 limGetMaxRateFlags(tpDphHashNode pStaDs,
void limDecrementPendingMgmtCount (tpAniSirGlobal pMac);
eHalStatus limTxBdComplete(tpAniSirGlobal pMac, void *pData);
+eHalStatus limAssocRspTxCompleteCnf(tpAniSirGlobal pMac, void *pData);
bool lim_is_robust_mgmt_action_frame(uint8 action_catagory);
tANI_U8 lim_compute_ext_cap_ie_length (tDot11fIEExtCap *ext_cap);
void lim_update_caps_info_for_bss(tpAniSirGlobal mac_ctx,
uint16_t *caps, uint16_t bss_caps);
-
+#ifdef SAP_AUTH_OFFLOAD
+void lim_sap_offload_add_sta(tpAniSirGlobal pmac,
+ tSapOfldAddStaIndMsg *lim_msgq);
+void lim_sap_offload_del_sta(tpAniSirGlobal pmac,
+ tSapOfldDelStaIndMsg *lim_msgq);
+#endif
#endif /* __LIM_UTILS_H */
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/lim_mbb.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/lim_mbb.c
new file mode 100644
index 00000000000..e9977b54c84
--- /dev/null
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/lim_mbb.c
@@ -0,0 +1,1754 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "aniGlobal.h"
+#include "limTypes.h"
+#include "limUtils.h"
+#include "limFT.h"
+#include "limSendMessages.h"
+#include "limAssocUtils.h"
+#include "limSerDesUtils.h"
+#include "limSmeReqUtils.h"
+#include "limAdmitControl.h"
+#include "sirApi.h"
+#include "rrmApi.h"
+#include "wlan_qct_tl.h"
+
+#define PREAUTH_REASSOC_TIMEOUT 500
+
+void lim_cleanup_connected_ap(tpAniSirGlobal mac, tpDphHashNode sta_ds,
+ tpPESession session_entry);
+
+/**
+ * lim_post_pre_auth_reassoc_rsp() -Posts preauth_reassoc response to SME
+ * @mac: MAC context
+ * @status: status
+ * @session_entry: session entry
+ * @reason: indicates which type of clean up needs to be performed
+ *
+ * This function process preauth_reassoc response to SME
+ */
+void lim_post_pre_auth_reassoc_rsp(tpAniSirGlobal mac,
+ tSirRetStatus status, tpPESession session_entry,
+ enum sir_roam_cleanup_type reason)
+{
+ tpSirFTPreAuthRsp pre_auth_rsp;
+ tSirMsgQ mmh_msg;
+ tANI_U16 rsp_len = sizeof(tSirFTPreAuthRsp);
+ tpPESession session_entry_con_ap;
+ tpDphHashNode sta_ds = NULL;
+
+ pre_auth_rsp = (tpSirFTPreAuthRsp)vos_mem_malloc(rsp_len);
+ if (NULL == pre_auth_rsp) {
+ limLog(mac, LOGE, FL("Failed to allocate memory"));
+ return;
+ }
+
+ limLog(mac, LOG1, FL("reason %d"), reason);
+
+ vos_mem_zero(pre_auth_rsp, rsp_len);
+ pre_auth_rsp->messageType = eWNI_SME_MBB_PRE_AUTH_REASSOC_RSP;
+ pre_auth_rsp->length = (tANI_U16)rsp_len;
+ pre_auth_rsp->status = status;
+ pre_auth_rsp->reason = reason;
+
+ if (session_entry)
+ pre_auth_rsp->smeSessionId = session_entry->smeSessionId;
+
+ /* The bssid of the AP we are sending Auth1 to. */
+ if (mac->ft.ftPEContext.pFTPreAuthReq)
+ sirCopyMacAddr(pre_auth_rsp->preAuthbssId,
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId);
+
+ if (status != eSIR_SUCCESS) {
+ limLog(mac, LOG1, FL("Pre-Auth Failed, Cleanup!"));
+ limLog(mac, LOG1, FL("flushing cached packets"));
+ WLANTL_PreAssocForward(false);
+
+ /*
+ * If reason is full clean up, add sme session id that
+ * will be useful in CSR during cleanup.
+ */
+ if (reason == SIR_MBB_DISCONNECTED) {
+ session_entry_con_ap =
+ (tpPESession)mac->ft.ftPEContext.psavedsessionEntry;
+ pre_auth_rsp->smeSessionId =
+ session_entry_con_ap->smeSessionId;
+ }
+ limFTCleanup(mac);
+ }
+
+ if (status == eSIR_SUCCESS) {
+ limLog(mac, LOG1, FL("Success"));
+
+ rsp_len = session_entry->assocReqLen + session_entry->assocRspLen +
+ session_entry->bcnLen;
+
+ pre_auth_rsp->roam_info = vos_mem_malloc(sizeof(tCsrRoamInfo));
+ if (pre_auth_rsp->roam_info == NULL) {
+ limLog(mac, LOGE,
+ FL("Failed to allocate memory for roam info"));
+ return;
+ }
+ vos_mem_set(pre_auth_rsp->roam_info, sizeof(tCsrRoamInfo), 0);
+
+ pre_auth_rsp->roam_info->pbFrames = vos_mem_malloc(rsp_len);
+ if (pre_auth_rsp->roam_info->pbFrames == NULL) {
+ limLog(mac, LOGE,
+ FL("Failed to allocate memory for roam info frames"));
+ return;
+ }
+ vos_mem_set(pre_auth_rsp->roam_info->pbFrames, rsp_len, 0);
+
+
+ pre_auth_rsp->length += rsp_len + sizeof(tCsrRoamInfo);
+
+ session_entry_con_ap =
+ (tpPESession)mac->ft.ftPEContext.psavedsessionEntry;
+ pre_auth_rsp->smeSessionId = session_entry_con_ap->smeSessionId;
+
+ if(session_entry->beacon != NULL) {
+ pre_auth_rsp->roam_info->nBeaconLength = session_entry->bcnLen;
+ vos_mem_copy(pre_auth_rsp->roam_info->pbFrames,
+ session_entry->beacon,
+ session_entry->bcnLen);
+ limLog(mac, LOG1, FL("Beacon len %d"), session_entry->bcnLen);
+
+ vos_mem_free(session_entry->beacon);
+ session_entry->beacon = NULL;
+ }
+
+ if(session_entry->assocReq != NULL) {
+ pre_auth_rsp->roam_info->nAssocReqLength =
+ session_entry->assocReqLen;
+ vos_mem_copy(pre_auth_rsp->roam_info->pbFrames +
+ session_entry->bcnLen,
+ session_entry->assocReq,
+ session_entry->assocReqLen);
+
+ vos_mem_free(session_entry->assocReq);
+ session_entry->assocReq = NULL;
+
+ limLog(mac, LOG1, FL("AssocReq len %d"), session_entry->assocReqLen);
+ }
+
+ if(session_entry->assocRsp != NULL) {
+ pre_auth_rsp->roam_info->nAssocRspLength =
+ session_entry->assocRspLen;
+ vos_mem_copy(pre_auth_rsp->roam_info->pbFrames +
+ session_entry->bcnLen + session_entry->assocReqLen,
+ session_entry->assocRsp,
+ session_entry->assocRspLen);
+
+ vos_mem_free(session_entry->assocRsp);
+ session_entry->assocRsp = NULL;
+
+ limLog(mac, LOG1, FL("AssocRsp len %d"), session_entry->assocRspLen);
+ }
+
+ sta_ds = dphGetHashEntry(mac, DPH_STA_HASH_INDEX_PEER,
+ &session_entry->dph.dphHashTable);
+ if(NULL == sta_ds) {
+ limLog(mac, LOGE,
+ FL("Unable to get the DPH Hash Entry for AID - %d"),
+ DPH_STA_HASH_INDEX_PEER);
+ return;
+ }
+
+ pre_auth_rsp->roam_info->staId = sta_ds->staIndex;
+ pre_auth_rsp->roam_info->ucastSig = sta_ds->ucUcastSig;
+ pre_auth_rsp->roam_info->bcastSig = sta_ds->ucBcastSig;
+ pre_auth_rsp->roam_info->maxRateFlags =
+ limGetMaxRateFlags(sta_ds, session_entry);
+ }
+
+ mmh_msg.type = pre_auth_rsp->messageType;
+ mmh_msg.bodyptr = pre_auth_rsp;
+ mmh_msg.bodyval = 0;
+
+ limLog(mac, LOG1,
+ FL("Posted Auth Rsp to SME with status of 0x%x"), status);
+
+ limSysProcessMmhMsgApi(mac, &mmh_msg, ePROT);
+}
+
+/*
+ * lim_reassoc_fail_cleanup() -handles cleanup during reassoc failure
+ * @mac: MAC context
+ * @status: status
+ * @data: pointer to data
+ *
+ * This function handles cleanup during reassoc failure
+ */
+void lim_reassoc_fail_cleanup(tpAniSirGlobal mac,
+ eHalStatus status, tANI_U32 *data)
+{
+ tpPESession session_entry;
+
+ session_entry = (tpPESession)data;
+
+ if (!mac->ft.ftPEContext.pFTPreAuthReq) {
+ limLog(mac, LOGE, FL("pFTPreAuthReq is NULL"));
+ return;
+ }
+
+ if (dphDeleteHashEntry(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId,
+ DPH_STA_HASH_INDEX_PEER,
+ &session_entry->dph.dphHashTable) != eSIR_SUCCESS) {
+ limLog(mac, LOGE, FL("error deleting hash entry"));
+ }
+
+ /* Delete session as session was created during preauth success */
+ peDeleteSession(mac, session_entry);
+
+ /* Add bss parameter cleanup happens as part of this processing*/
+ if ((status == eHAL_STATUS_MBB_DEL_BSS_FAIL) ||
+ (status == eHAL_STATUS_INVALID_PARAMETER) ||
+ (status == eHAL_STATUS_MBB_ADD_BSS_FAIL))
+ lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL,
+ SIR_MBB_DISCONNECTED);
+ else
+ lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL,
+ SIR_MBB_CONNECTED);
+}
+
+/*
+ * lim_perform_post_reassoc_mbb_channel_change() -invokes resume callback
+ * @mac: MAC context
+ * @status: status
+ * @data: pointer to data
+ * @session_entry: session entry
+ *
+ * This function invokes resume callback
+ */
+void lim_perform_post_reassoc_mbb_channel_change(tpAniSirGlobal mac,
+ eHalStatus status, tANI_U32 *data, tpPESession session_entry)
+{
+ tpPESession session_entry_con_ap;
+ tANI_U8 session_id;
+
+ session_entry_con_ap = peFindSessionByBssid(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->currbssId,
+ &session_id);
+ if (session_entry_con_ap == NULL) {
+ limLog(mac, LOGE,
+ FL("session does not exist for given BSSID" MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(mac->ft.ftPEContext.pFTPreAuthReq->currbssId));
+
+ lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL,
+ SIR_MBB_CONNECTED);
+ return;
+ }
+
+ peSetResumeChannel(mac, session_entry_con_ap->currentOperChannel, 0);
+ limResumeLink(mac, lim_reassoc_fail_cleanup,
+ (tANI_U32 *)session_entry);
+}
+
+/*
+ * lim_handle_reassoc_mbb_fail() -handles reassoc failure
+ * @mac: MAC context
+ * @session_entry: session entry
+ *
+ * This function handles reassoc failure
+ */
+void lim_handle_reassoc_mbb_fail(tpAniSirGlobal mac,
+ tpPESession session_entry)
+{
+ tpPESession session_entry_con_ap;
+ tANI_U8 session_id;
+
+ session_entry_con_ap = peFindSessionByBssid(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->currbssId,
+ &session_id);
+ if (session_entry_con_ap == NULL) {
+ limLog(mac, LOGE,
+ FL("session does not exist for given BSSID" MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(mac->ft.ftPEContext.pFTPreAuthReq->currbssId));
+
+ lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL,
+ SIR_MBB_CONNECTED);
+ return;
+ }
+
+ limLog(mac, LOG1, FL("currentOperChannel %d preAuthchannelNum %d"),
+ session_entry_con_ap->currentOperChannel,
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum);
+
+ /* Restore set link to post assoc for currently connected AP */
+ if (limSetLinkState(mac, eSIR_LINK_POSTASSOC_STATE,
+ session_entry_con_ap->bssId,
+ session_entry_con_ap->selfMacAddr,
+ NULL, NULL) != eSIR_SUCCESS) {
+ limLog(mac, LOGE, FL("Set link state to POSTASSOC failed"));
+
+ lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL,
+ SIR_MBB_CONNECTED);
+ return;
+ }
+
+ /* Change channel if required as channel might be changed during preauth */
+ if (session_entry_con_ap->currentOperChannel !=
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum) {
+ limChangeChannelWithCallback(mac,
+ session_entry_con_ap->currentOperChannel,
+ lim_perform_post_reassoc_mbb_channel_change, NULL, session_entry);
+ } else {
+ /*
+ * Link needs to be resumed as link was suspended
+ * for same channel during preauth.
+ */
+ peSetResumeChannel(mac, session_entry_con_ap->currentOperChannel, 0);
+ limResumeLink(mac, lim_reassoc_fail_cleanup,
+ (tANI_U32 *)session_entry);
+ }
+}
+
+/*
+ * lim_preauth_fail_cleanup() -handles cleanup during preauth failure
+ * @mac: MAC context
+ * @status: status
+ * @data: pointer to data
+ *
+ * This function handles cleanup during reassoc failure
+ */
+void lim_preauth_fail_cleanup(tpAniSirGlobal mac,
+ eHalStatus status, tANI_U32 *data)
+{
+ tpPESession session_entry;
+
+ session_entry = (tpPESession)data;
+
+ lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL,
+ SIR_MBB_CONNECTED);
+}
+
+/*
+ * lim_perform_preauth_mbb_fail_channel_change() -invokes resume callback
+ * @mac: MAC context
+ * @status: status
+ * @data: pointer to data
+ * @session_entry: session entry
+ *
+ * This function invokes resume callback
+ */
+void lim_perform_preauth_mbb_fail_channel_change(tpAniSirGlobal mac,
+ eHalStatus status, tANI_U32 *data, tpPESession session_entry)
+{
+ peSetResumeChannel(mac, session_entry->currentOperChannel, 0);
+ limResumeLink(mac, lim_preauth_fail_cleanup,
+ (tANI_U32 *)session_entry);
+}
+
+/*
+ * lim_handle_preauth_mbb_fail() -handles preauth failure
+ * @mac: MAC context
+ * @session_entry: session entry
+ *
+ * This function handles reassoc failure
+ */
+void lim_handle_preauth_mbb_fail(tpAniSirGlobal mac,
+ tpPESession session_entry)
+{
+ limLog(mac, LOG1, FL("currentOperChannel %d preAuthchannelNum %d"),
+ session_entry->currentOperChannel,
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum);
+
+ /* Restore set link to post assoc for currently connected AP */
+ if (limSetLinkState(mac, eSIR_LINK_POSTASSOC_STATE,
+ session_entry->bssId,
+ session_entry->selfMacAddr,
+ NULL, NULL) != eSIR_SUCCESS) {
+ limLog(mac, LOGE, FL("Set link state to POSTASSOC failed"));
+
+ lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL,
+ SIR_MBB_CONNECTED);
+ return;
+ }
+
+ /* Change channel if required as channel might be changed during preauth */
+ if (session_entry->currentOperChannel !=
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum) {
+ limChangeChannelWithCallback(mac,
+ session_entry->currentOperChannel,
+ lim_perform_preauth_mbb_fail_channel_change, NULL, session_entry);
+ } else {
+ /*
+ * Link needs to be resumed as link was suspended
+ * for same channel during preauth.
+ */
+ peSetResumeChannel(mac, session_entry->currentOperChannel, 0);
+ limResumeLink(mac, lim_preauth_fail_cleanup,
+ (tANI_U32 *)session_entry);
+ }
+}
+
+
+/*
+ * lim_del_sta_mbb() -performs del sta
+ * @mac: MAC context
+ * @sta_ds_connected_ap: station entry of connected AP
+ * @resp_reqd: indicates whether response is required or not
+ * @session_entry_connected_ap: session entry of connected AP
+ *
+ * This function performs del sta
+ */
+tSirRetStatus lim_del_sta_mbb(tpAniSirGlobal mac,
+ tpDphHashNode sta_ds_connected_ap,
+ tANI_BOOLEAN resp_reqd,
+ tpPESession session_entry_connected_ap)
+{
+ tpDeleteStaParams del_sta_params;
+ tSirMsgQ msg;
+ tSirRetStatus ret_code;
+
+ del_sta_params = vos_mem_malloc(sizeof(*del_sta_params));
+ if (NULL == del_sta_params) {
+ limLog(mac, LOGE, FL("Unable to allocate memory during DEL_STA" ));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ vos_mem_zero(del_sta_params, sizeof(*del_sta_params));
+
+ del_sta_params->sessionId = session_entry_connected_ap->peSessionId;
+ del_sta_params->status = eHAL_STATUS_SUCCESS;
+
+#ifdef FEATURE_WLAN_TDLS
+ if(((eLIM_STA_ROLE == GET_LIM_SYSTEM_ROLE(session_entry_connected_ap)) &&
+ (sta_ds_connected_ap->staType != STA_ENTRY_TDLS_PEER)) ||
+ (eLIM_BT_AMP_STA_ROLE ==
+ GET_LIM_SYSTEM_ROLE(session_entry_connected_ap)))
+#else
+ if((eLIM_STA_ROLE == GET_LIM_SYSTEM_ROLE(session_entry_connected_ap)) ||
+ (eLIM_BT_AMP_STA_ROLE ==
+ GET_LIM_SYSTEM_ROLE(session_entry_connected_ap)))
+#endif
+ del_sta_params->staIdx = session_entry_connected_ap->staId;
+ else
+ del_sta_params->staIdx = sta_ds_connected_ap->staIndex;
+
+ del_sta_params->assocId = sta_ds_connected_ap->assocId;
+ del_sta_params->respReqd = resp_reqd;
+
+ /* Change Mlm state of connected AP to Del sta rsp state */
+ session_entry_connected_ap->limMlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;
+ MTRACE(macTrace(mac, TRACE_CODE_MLM_STATE,
+ session_entry_connected_ap->peSessionId, eLIM_MLM_WT_DEL_STA_RSP_STATE));
+
+ msg.type = WDA_DELETE_STA_REQ;
+ msg.reserved = 0;
+ msg.bodyptr = del_sta_params;
+ msg.bodyval = 0;
+
+ limLog(mac, LOG1,
+ FL("sessionId %d staIdx: %d assocId: %d for "MAC_ADDRESS_STR),
+ del_sta_params->sessionId, del_sta_params->staIdx,
+ del_sta_params->assocId,
+ MAC_ADDR_ARRAY(sta_ds_connected_ap->staAddr));
+
+ MTRACE(macTraceMsgTx(mac, session_entry_connected_ap->peSessionId,
+ msg.type));
+
+ ret_code = wdaPostCtrlMsg(mac, &msg);
+ if( eSIR_SUCCESS != ret_code) {
+ if(resp_reqd)
+ SET_LIM_PROCESS_DEFD_MESGS(mac, true);
+ limLog(mac, LOGE,
+ FL("Posting DELETE_STA_REQ failed, reason=%X"), ret_code);
+ vos_mem_free(del_sta_params);
+ }
+
+ return ret_code;
+}
+
+/*
+ * lim_del_bss_mbb() -performs del bss of connected AP
+ * @mac: MAC context
+ * @sta_ds: station entry
+ * @bss_idx:BSS index
+ * @session_entry: session entry
+ *
+ * This function performs del bss of connected AP
+ */
+tSirRetStatus lim_del_bss_mbb(tpAniSirGlobal mac, tpDphHashNode sta_ds,
+ tANI_U16 bss_idx,tpPESession session_entry)
+{
+ tpDeleteBssParams delbss_params = NULL;
+ tSirMsgQ msg;
+ tSirRetStatus ret_code = eSIR_SUCCESS;
+
+ delbss_params = vos_mem_malloc(sizeof(tDeleteBssParams));
+ if (NULL == delbss_params) {
+ limLog(mac, LOGE,
+ FL("Unable to allocate memory during del bss" ));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ vos_mem_set((tANI_U8 *) delbss_params, sizeof(tDeleteBssParams), 0);
+
+ delbss_params->sessionId = session_entry->peSessionId;
+
+ if (sta_ds != NULL) {
+ delbss_params->bssIdx = sta_ds->bssId;
+ sta_ds->valid = 0;
+ sta_ds->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_BSS_RSP_STATE;
+ }
+ else
+ delbss_params->bssIdx = bss_idx;
+
+ session_entry->limMlmState = eLIM_MLM_WT_DEL_BSS_RSP_STATE;
+ MTRACE(macTrace(mac, TRACE_CODE_MLM_STATE,
+ session_entry->peSessionId, eLIM_MLM_WT_DEL_BSS_RSP_STATE));
+
+ delbss_params->status= eHAL_STATUS_SUCCESS;
+ delbss_params->respReqd = 1;
+
+ limLog(mac, LOG1, FL("Sessionid %d bss idx: %x BSSID:" MAC_ADDRESS_STR),
+ delbss_params->sessionId, delbss_params->bssIdx,
+ MAC_ADDR_ARRAY(session_entry->bssId));
+
+ /* we need to defer the message until we get the response back from HAL. */
+ SET_LIM_PROCESS_DEFD_MESGS(mac, false);
+
+ msg.type = WDA_DELETE_BSS_REQ;
+ msg.reserved = 0;
+ msg.bodyptr = delbss_params;
+ msg.bodyval = 0;
+
+ MTRACE(macTraceMsgTx(mac, session_entry->peSessionId, msg.type));
+
+ if(eSIR_SUCCESS != (ret_code = wdaPostCtrlMsg(mac, &msg)))
+ {
+ SET_LIM_PROCESS_DEFD_MESGS(mac, true);
+ limLog(mac, LOGE,
+ FL("Posting DELETE_BSS_REQ to HAL failed, reason=%X"), ret_code);
+ vos_mem_free(delbss_params);
+ }
+
+ return ret_code;
+}
+
+/*
+ * lim_add_bss_mbb() -performs add bss of new roamable AP
+ * @mac: MAC context
+ * @sta_ds: station entry
+ * @bss_idx:BSS index
+ * @session_entry: session entry
+ *
+ * This function performs add bss of new roamable AP
+ */
+void lim_add_bss_mbb(tpAniSirGlobal mac, tpDphHashNode sta_ds,
+ tpPESession session_entry)
+{
+ tSirMsgQ msg;
+ tSirRetStatus ret_code;
+
+ /* we need to defer the message until we get the response back from HAL. */
+ SET_LIM_PROCESS_DEFD_MESGS(mac, false);
+
+ msg.type = SIR_HAL_ADD_BSS_REQ;
+ msg.reserved = 0;
+ msg.bodyptr = mac->ft.ftPEContext.pAddBssReq;
+ msg.bodyval = 0;
+
+ limLog(mac, LOG1, FL("Sending SIR_HAL_ADD_BSS_REQ"));
+
+ session_entry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE;
+
+ MTRACE(macTrace(mac, TRACE_CODE_MLM_STATE,
+ session_entry->peSessionId, eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE));
+
+ MTRACE(macTraceMsgTx(mac, session_entry->peSessionId, msg.type));
+
+ ret_code = wdaPostCtrlMsg(mac, &msg);
+ if( eSIR_SUCCESS != ret_code) {
+ vos_mem_free(mac->ft.ftPEContext.pAddBssReq);
+ limLog(mac, LOGE,
+ FL("Posting ADD_BSS_REQ to HAL failed, reason=%X"), ret_code);
+ }
+ /* Dont need this anymore */
+ mac->ft.ftPEContext.pAddBssReq = NULL;
+}
+
+tSirRetStatus lim_add_sta_mbb(tpAniSirGlobal mac, tANI_U16 assoc_id,
+ tpPESession session_entry)
+{
+ tpAddStaParams add_sta_params = NULL;
+ tSirMsgQ msg;
+ tSirRetStatus retCode = eSIR_SUCCESS;
+
+ add_sta_params = mac->ft.ftPEContext.pAddStaReq;
+ add_sta_params->assocId = assoc_id;
+
+ msg.type = SIR_HAL_ADD_STA_REQ;
+ msg.reserved = 0;
+ msg.bodyptr = add_sta_params;
+ msg.bodyval = 0;
+
+ limLog(mac, LOG1,
+ FL("Sending SIR_HAL_ADD_STA_REQ. aid %d)"),
+ add_sta_params->assocId);
+
+ session_entry->limPrevMlmState = session_entry->limMlmState;
+ session_entry->limMlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE;
+
+ MTRACE(macTrace(mac, TRACE_CODE_MLM_STATE,
+ session_entry->peSessionId, eLIM_MLM_WT_ADD_STA_RSP_STATE));
+
+ MTRACE(macTraceMsgTx(mac, session_entry->peSessionId, msg.type));
+
+ if(eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( mac, &msg))) {
+ limLog(mac, LOGE,
+ FL("Posting ADD_STA_REQ to HAL failed, reason=%X"), retCode);
+ vos_mem_free(add_sta_params);
+ }
+
+ mac->ft.ftPEContext.pAddStaReq = NULL;
+ return retCode;
+}
+
+/*
+ * lim_handle_reassoc_mbb_success() -handles reassoc success
+ * @mac: MAC context
+ * @session_entry: session entry
+ * @assoc_rsp: pointer to assoc response
+ * @sta_ds : station entry
+ *
+ * This function handles reassoc success
+ */
+void lim_handle_reassoc_mbb_success(tpAniSirGlobal mac,
+ tpPESession session_entry, tpSirAssocRsp assoc_rsp, tpDphHashNode sta_ds)
+{
+ tpPESession session_entry_con_ap;
+ tANI_U8 session_id_connected_ap;
+ tpDphHashNode sta_ds_connected_ap;
+ tANI_U16 aid;
+ tSirRetStatus ret_code;
+
+ limUpdateAssocStaDatas(mac, sta_ds, assoc_rsp, session_entry);
+
+ /* Store assigned AID for TIM processing */
+ session_entry->limAID = assoc_rsp->aid & 0x3FFF;
+
+ /* De register STA for currently connected AP */
+ mac->sme.roaming_mbb_callback(mac, mac->ft.ftSmeContext.smeSessionId,
+ NULL, NULL, SIR_ROAMING_DEREGISTER_STA);
+
+ mac->sme.roaming_mbb_callback(mac, mac->ft.ftSmeContext.smeSessionId,
+ NULL, NULL, SIR_STOP_ROAM_OFFLOAD_SCAN);
+
+ if((session_entry_con_ap = peFindSessionByBssid(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->currbssId,
+ &session_id_connected_ap))== NULL) {
+ limLog(mac, LOGE,
+ FL("session does not exist for given BSSID" MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(mac->ft.ftPEContext.pFTPreAuthReq->currbssId));
+ goto end;
+ }
+
+ session_entry->smeSessionId = session_entry_con_ap->smeSessionId;
+
+ sta_ds_connected_ap = dphLookupHashEntry(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->currbssId,
+ &aid,
+ &session_entry_con_ap->dph.dphHashTable);
+ if (sta_ds_connected_ap == NULL) {
+ limLog(mac, LOGE,
+ FL("sta_ds NULL for given BSSID" MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(mac->ft.ftPEContext.pFTPreAuthReq->currbssId));
+ goto end;
+ }
+
+ /*
+ * Change Mlm state of new AP to Del sta rsp state so that
+ * duplicate reassoc response will be dropped.
+ */
+ session_entry->limMlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;
+ MTRACE(macTrace(mac, TRACE_CODE_MLM_STATE,
+ session_entry->peSessionId, eLIM_MLM_WT_DEL_STA_RSP_STATE));
+
+ /* Delete sta for currently connected AP */
+ ret_code = lim_del_sta_mbb(mac, sta_ds_connected_ap,
+ false, session_entry_con_ap);
+ if (ret_code == eSIR_SUCCESS)
+ return;
+
+end:
+ /* Connected AP lim cleanup.*/
+ lim_cleanup_connected_ap(mac, sta_ds_connected_ap, session_entry_con_ap);
+ /*
+ * eHAL_STATUS_INVALID_PARAMETER is used
+ * so that full cleanup is triggered.
+ */
+ lim_reassoc_fail_cleanup(mac, eHAL_STATUS_INVALID_PARAMETER,
+ (tANI_U32 *)session_entry);
+}
+
+
+/*
+ * lim_process_preauth_mbb_result() -process pre auth result
+ * @mac: MAC context
+ * @status: status
+ * @data: pointer to data
+ *
+ * This function invokes resume callback
+ */
+static inline void lim_process_preauth_mbb_result(tpAniSirGlobal mac,
+ eHalStatus status, tANI_U32 *data)
+{
+ tpPESession session_entry, ft_session_entry;
+ tpDphHashNode sta_ds;
+ tAddBssParams *add_bss_params;
+ tSirSmeJoinReq *reassoc_req;
+ tLimMlmReassocReq *mlm_reassoc_req;
+ tANI_U16 caps;
+ tANI_U16 nSize;
+ tpSirSmeJoinReq pReassocReq = NULL;
+
+ if (!mac->ft.ftPEContext.pFTPreAuthReq) {
+ limLog(mac, LOG1, "Pre-Auth request is NULL!");
+ goto end;
+ }
+
+ session_entry = (tpPESession)data;
+
+ /* Post the FT Pre Auth Response to SME in case of failure*/
+ if (mac->ft.ftPEContext.ftPreAuthStatus == eSIR_FAILURE)
+ goto end;
+
+ /* Flow for preauth success */
+ limFTSetupAuthSession(mac, session_entry);
+
+ /*
+ * Prepare reassoc request. Memory allocated for tSirSmeJoinReq
+ *reassoc_req in csr_fill_reassoc_req. Free that memory here.
+ */
+ mac->sme.roaming_mbb_callback(mac, mac->ft.ftSmeContext.smeSessionId,
+ mac->ft.ftPEContext.pFTPreAuthReq->pbssDescription,
+ &reassoc_req, SIR_PREPARE_REASSOC_REQ);
+ if (reassoc_req == NULL) {
+ limLog(mac, LOGE,
+ FL("reassoc req is NULL"));
+ goto end;
+ }
+
+ nSize = __limGetSmeJoinReqSizeForAlloc((tANI_U8 *) reassoc_req);
+ pReassocReq = vos_mem_malloc(nSize);
+ if ( NULL == pReassocReq )
+ {
+ limLog(mac, LOGE,
+ FL("call to AllocateMemory failed for pReassocReq"));
+ goto end;
+ }
+ vos_mem_set((void *) pReassocReq, nSize, 0);
+ if ((limJoinReqSerDes(mac, (tpSirSmeJoinReq) pReassocReq,
+ (tANI_U8 *) reassoc_req) == eSIR_FAILURE) ||
+ (!limIsSmeJoinReqValid(mac,
+ (tpSirSmeJoinReq) pReassocReq)))
+ {
+ limLog(mac, LOGE,
+ FL("received SME_REASSOC_REQ with invalid data"));
+ goto end;
+ }
+
+ ft_session_entry = mac->ft.ftPEContext.pftSessionEntry;
+
+ ft_session_entry->pLimReAssocReq = pReassocReq;
+ vos_mem_free(reassoc_req);
+
+ add_bss_params = mac->ft.ftPEContext.pAddBssReq;
+
+ mlm_reassoc_req = vos_mem_malloc(sizeof(tLimMlmReassocReq));
+ if (NULL == mlm_reassoc_req) {
+ limLog(mac, LOGE,
+ FL("call to AllocateMemory failed for mlmReassocReq"));
+ goto end;
+ }
+
+ vos_mem_copy(mlm_reassoc_req->peerMacAddr,
+ ft_session_entry->limReAssocbssId,
+ sizeof(tSirMacAddr));
+ mlm_reassoc_req->reassocFailureTimeout = PREAUTH_REASSOC_TIMEOUT;
+
+ if (cfgGetCapabilityInfo(mac, &caps, ft_session_entry) != eSIR_SUCCESS) {
+ limLog(mac, LOGE, FL("could not retrieve Capabilities value"));
+ vos_mem_free(mlm_reassoc_req);
+ goto end;
+ }
+
+ lim_update_caps_info_for_bss(mac, &caps,
+ reassoc_req->bssDescription.capabilityInfo);
+
+ limLog(mac, LOG1, FL("Capabilities info Reassoc: 0x%X"), caps);
+
+ mlm_reassoc_req->capabilityInfo = caps;
+ mlm_reassoc_req->sessionId = ft_session_entry->peSessionId;
+ mlm_reassoc_req->listenInterval = WNI_CFG_LISTEN_INTERVAL_STADEF;
+
+ if ((sta_ds = dphAddHashEntry(mac, add_bss_params->bssId,
+ DPH_STA_HASH_INDEX_PEER,
+ &ft_session_entry->dph.dphHashTable)) == NULL) {
+ limLog(mac, LOGE, FL("could not add hash entry at DPH"));
+ limPrintMacAddr(mac, add_bss_params->bssId, LOGE);
+ vos_mem_free(mlm_reassoc_req);
+ goto end;
+ }
+
+ /* Start timer here to handle reassoc timeout */
+ mac->lim.limTimers.glim_reassoc_mbb_rsp_timer.sessionId =
+ ft_session_entry->peSessionId;
+
+ MTRACE(macTrace(mac, TRACE_CODE_TIMER_ACTIVATE,
+ session_entry->peSessionId, eLIM_REASSOC_MBB_RSP_TIMER));
+
+ if(TX_SUCCESS !=
+ tx_timer_activate(&mac->lim.limTimers.glim_reassoc_mbb_rsp_timer)) {
+ limLog(mac, LOGE, FL("Reassoc MBB Rsp Timer Start Failed"));
+
+ if (ft_session_entry->pLimReAssocReq) {
+ vos_mem_free(ft_session_entry->pLimReAssocReq);
+ ft_session_entry->pLimReAssocReq = NULL;
+ }
+
+ vos_mem_free(mlm_reassoc_req);
+ goto end;
+ }
+
+ limLog(mac, LOG1, FL("enabling caching"));
+ WLANTL_EnablePreAssocCaching();
+
+ /* To do: Add changes for reassoc fail timer */
+ limSendReassocReqWithFTIEsMgmtFrame(mac,
+ mlm_reassoc_req, ft_session_entry);
+
+ ft_session_entry->limMlmState = eLIM_MLM_WT_REASSOC_RSP_STATE;
+
+ limLog(mac, LOG1, FL("Set the mlm state to %d session=%d"),
+ ft_session_entry->limMlmState, ft_session_entry->peSessionId);
+ return;
+
+end:
+ lim_handle_reassoc_mbb_fail(mac, ft_session_entry);
+}
+
+/*
+ * lim_perform_post_preauth_mbb_channel_change() -invokes resume callback
+ * @mac: MAC context
+ * @status: status
+ * @data: pointer to data
+ * @session_entry: session entry
+ *
+ * This function invokes resume callback after successful reception of
+ * pre auth
+ */
+static inline
+void lim_perform_post_preauth_mbb_channel_change(tpAniSirGlobal mac,
+ eHalStatus status, tANI_U32 *data, tpPESession session_entry)
+{
+ peSetResumeChannel(mac, 0, 0);
+ limResumeLink(mac, lim_process_preauth_mbb_result,
+ (tANI_U32 *)session_entry);
+}
+
+/*
+ * lim_handle_pre_auth_mbb_rsp() -handles preauth response
+ * @mac: MAC context
+ * @status: status of message
+ * @session_entry: session entry
+ *
+ * This function process preauth response
+ */
+void lim_handle_pre_auth_mbb_rsp(tpAniSirGlobal mac,
+ tSirRetStatus status, tpPESession session_entry)
+{
+ tpPESession ft_session_entry;
+ tANI_U8 session_id;
+ tpSirBssDescription bss_description;
+
+ mac->ft.ftPEContext.ftPreAuthStatus = status;
+
+ mac->ft.ftPEContext.saved_auth_rsp_length = 0;
+
+ limLog(mac, LOG1, FL("preauth status %d"),
+ mac->ft.ftPEContext.ftPreAuthStatus);
+
+ /* Create FT session for the re-association at this point */
+ if (mac->ft.ftPEContext.ftPreAuthStatus == eSIR_SUCCESS) {
+ bss_description = mac->ft.ftPEContext.pFTPreAuthReq->pbssDescription;
+ if((ft_session_entry = peCreateSession(mac, bss_description->bssId,
+ &session_id, mac->lim.maxStation)) == NULL) {
+ limLog(mac, LOGE,
+ FL("session can not be created for pre-auth AP"));
+ mac->ft.ftPEContext.ftPreAuthStatus = eSIR_FAILURE;
+ goto out;
+ }
+ ft_session_entry->peSessionId = session_id;
+ sirCopyMacAddr(ft_session_entry->selfMacAddr,
+ session_entry->selfMacAddr);
+ sirCopyMacAddr(ft_session_entry->limReAssocbssId,
+ bss_description->bssId);
+ ft_session_entry->bssType = session_entry->bssType;
+
+ if (ft_session_entry->bssType == eSIR_INFRASTRUCTURE_MODE)
+ ft_session_entry->limSystemRole = eLIM_STA_ROLE;
+
+ ft_session_entry->limSmeState = eLIM_SME_WT_REASSOC_STATE;
+ mac->ft.ftPEContext.pftSessionEntry = ft_session_entry;
+ limLog(mac, LOG1,"%s:created session (%p) with id = %d",
+ __func__, ft_session_entry, ft_session_entry->peSessionId);
+
+ /* Update the ReAssoc BSSID of the current session */
+ sirCopyMacAddr(session_entry->limReAssocbssId, bss_description->bssId);
+ limPrintMacAddr(mac, session_entry->limReAssocbssId, LOG1);
+
+ /* Prepare session for roamable AP */
+ lim_process_preauth_mbb_result(mac,
+ mac->ft.ftPEContext.ftPreAuthStatus, (tANI_U32 *)session_entry);
+ return;
+ }else {
+ lim_handle_preauth_mbb_fail(mac, session_entry);
+ return;
+ }
+
+out:
+ /* This sequence needs to be executed in case of failure*/
+ if (session_entry->currentOperChannel !=
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum) {
+ limChangeChannelWithCallback(mac, session_entry->currentOperChannel,
+ lim_perform_post_preauth_mbb_channel_change, NULL, session_entry);
+ } else {
+ /* Link needs to be resumed as link was suspended for same channel */
+ peSetResumeChannel(mac, 0, 0);
+ limResumeLink(mac, lim_process_preauth_mbb_result,
+ (tANI_U32 *)session_entry);
+ }
+}
+
+/**
+ * lim_process_preauth_mbb_rsp_timeout() -Process preauth response timeout
+ * @mac: MAC context
+ *
+ * This function is called if preauth response is not received from the AP
+ * within timeout
+ */
+void lim_process_preauth_mbb_rsp_timeout(tpAniSirGlobal mac)
+{
+ tpPESession session_entry;
+
+ /*
+ * Pre auth is failed. Need to resume link and get back on
+ * to home channel.
+ */
+ limLog(mac, LOG1, FL("Pre-Auth MBB Time Out!!!!"));
+
+ if((session_entry = peFindSessionBySessionId(mac,
+ mac->lim.limTimers.glim_pre_auth_mbb_rsp_timer.sessionId))== NULL) {
+ limLog(mac, LOGE, FL("session does not exist for given session id"));
+ return;
+ }
+
+ /*
+ * To handle the race condition where we recieve preauth rsp after
+ * timer has expired.
+ */
+ if (mac->ft.ftPEContext.pFTPreAuthReq == NULL) {
+ limLog(mac, LOGE, FL("Auth Rsp might already be posted to SME"
+ "and cleanup done! sessionId:%d"),
+ mac->lim.limTimers.glim_pre_auth_mbb_rsp_timer.sessionId);
+ return;
+ }
+
+ if (eANI_BOOLEAN_TRUE ==
+ mac->ft.ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed) {
+ limLog(mac, LOGE,
+ FL("Auth rsp already posted to SME session %p"), session_entry);
+ return;
+ } else {
+ /*
+ * Here we are sending preauth rsp with failure state
+ * and which is forwarded to SME. Now, if we receive an preauth
+ * resp from AP with success it would create a FT pesession, but
+ * will be dropped in SME leaving behind the pesession.
+ * Mark Preauth rsp processed so that any rsp from AP is dropped in
+ * limProcessAuthFrameNoSession.
+ */
+ limLog(mac,LOG1,
+ FL("Auth rsp not yet posted to SME session %p)"), session_entry);
+ mac->ft.ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed =
+ eANI_BOOLEAN_TRUE;
+ }
+ /*
+ * Ok, so attempted a Pre-Auth and failed. If we are off channel. We need
+ * to get back.
+ */
+ lim_handle_pre_auth_mbb_rsp(mac, eSIR_FAILURE, session_entry);
+ }
+
+/**
+ * lim_process_reassoc_mbb_rsp_timeout() -Process reassoc response timeout
+ * @mac: MAC context
+ *
+ * This function is called if preauth response is not received from the
+ * AP within timeout
+ */
+void lim_process_reassoc_mbb_rsp_timeout(tpAniSirGlobal mac)
+{
+ tpPESession session_entry, ft_session_entry;
+ tANI_U8 session_id;
+
+ if((ft_session_entry = peFindSessionBySessionId(mac,
+ mac->lim.limTimers.glim_reassoc_mbb_rsp_timer.sessionId))== NULL) {
+ limLog(mac, LOGE,
+ FL("ft session does not exist for given session id %d"),
+ mac->lim.limTimers.glim_reassoc_mbb_rsp_timer.sessionId);
+ return;
+ }
+
+ limLog(mac, LOG1, FL("Reassoc timeout happened in state %d"),
+ ft_session_entry->limMlmState);
+
+ if((session_entry = peFindSessionByBssid(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->currbssId, &session_id))== NULL) {
+ limLog(mac, LOGE,
+ FL("session does not exist for given BSSID" MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(mac->ft.ftPEContext.pFTPreAuthReq->currbssId));
+ return;
+ }
+
+ lim_handle_reassoc_mbb_fail(mac, ft_session_entry);
+
+}
+
+
+/**
+ * lim_perform_pre_auth_reassoc() -Sends preauth request
+ * @mac: MAC context
+ * @status: status of message
+ * @data: gives information of session
+ * @session_entry: session entry
+ *
+ * This function process preauth request received from CSR
+ */
+static inline
+void lim_perform_pre_auth_reassoc(tpAniSirGlobal mac, eHalStatus status,
+ tANI_U32 *data, tpPESession session_entry)
+{
+ tSirMacAuthFrameBody authFrame;
+
+ if (status != eHAL_STATUS_SUCCESS) {
+ limLog(mac, LOGE,
+ FL("Change channel not successful for pre-auth"));
+ goto preauth_fail;
+ }
+
+ limLog(mac, LOGE,
+ FL("session id %d"), session_entry->peSessionId);
+
+ mac->ft.ftPEContext.psavedsessionEntry = session_entry;
+
+ authFrame.authAlgoNumber = eSIR_OPEN_SYSTEM;
+ authFrame.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1;
+ authFrame.authStatusCode = 0;
+
+ /* Start timer here to come back to operating channel. */
+ mac->lim.limTimers.glim_pre_auth_mbb_rsp_timer.sessionId =
+ session_entry->peSessionId;
+
+ limSendAuthMgmtFrame(mac, &authFrame,
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId,
+ LIM_NO_WEP_IN_FC, session_entry, eSIR_FALSE);
+
+ MTRACE(macTrace(mac, TRACE_CODE_TIMER_ACTIVATE,
+ session_entry->peSessionId, eLIM_PREAUTH_MBB_RSP_TIMER));
+
+ if(TX_SUCCESS !=
+ tx_timer_activate(&mac->lim.limTimers.glim_pre_auth_mbb_rsp_timer)) {
+ limLog(mac, LOGE, FL("Pre Auth MBB Rsp Timer Start Failed"));
+
+ mac->ft.ftPEContext.psavedsessionEntry = NULL;
+ goto preauth_fail;
+ }
+
+ return;
+
+preauth_fail:
+ lim_handle_pre_auth_mbb_rsp(mac, eSIR_FAILURE, session_entry);
+ return;
+}
+
+/**
+ * pre_auth_mbb_suspend_link_handler() -Handler for suspend link
+ * @mac: MAC context
+ * @status: status of message
+ * @data: gives information of session
+ *
+ * This function process preauth request received from CSR
+ */
+static inline
+void pre_auth_mbb_suspend_link_handler(tpAniSirGlobal mac,
+ eHalStatus status, tANI_U32 *data)
+{
+ tpPESession session_entry;
+
+ if (status != eHAL_STATUS_SUCCESS) {
+ limLog(mac, LOGE, FL("Link suspend failed"));
+ lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE,
+ (tpPESession)data, SIR_MBB_CONNECTED);
+ return;
+ }
+
+ session_entry = (tpPESession)data;
+
+ if (session_entry->currentOperChannel !=
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum) {
+ limChangeChannelWithCallback(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum,
+ lim_perform_pre_auth_reassoc, NULL, session_entry);
+ return;
+ } else {
+ lim_perform_pre_auth_reassoc(mac, eHAL_STATUS_SUCCESS,
+ NULL, session_entry);
+ return;
+ }
+}
+
+/**
+ * lim_process_pre_auth_reassoc_req() -Process preauth request
+ * @hal: HAL context
+ * @msg: message
+ *
+ * This function process preauth request received from CSR
+ */
+void lim_process_pre_auth_reassoc_req(tpAniSirGlobal mac, tpSirMsgQ msg)
+{
+ tpPESession session_entry;
+ tANI_U8 session_id;
+
+ limFTInit(mac);
+
+ /* Can set it only after sending auth */
+ mac->ft.ftPEContext.ftPreAuthStatus = eSIR_FAILURE;
+
+ /* We need information from the Pre-Auth Req. Lets save that */
+ mac->ft.ftPEContext.pFTPreAuthReq = (tpSirFTPreAuthReq)msg->bodyptr;
+ if (!mac->ft.ftPEContext.pFTPreAuthReq) {
+ limLog(mac, LOGE,
+ FL("pFTPreAuthReq is NULL"));
+ lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL,
+ SIR_MBB_CONNECTED);
+ return;
+ }
+
+ /* Get the current session entry */
+ session_entry = peFindSessionByBssid(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->currbssId, &session_id);
+ if (session_entry == NULL) {
+ limLog(mac, LOGE,
+ FL("Unable to find session for the following bssid"));
+ limPrintMacAddr(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->currbssId, LOGE);
+
+ /* Post the pre auth response to SME */
+ lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL,
+ SIR_MBB_CONNECTED);
+ return;
+ }
+
+ limLog(mac, LOG1,
+ FL("set link with eSIR_LINK_PRE_AUTH_REASSOC_STATE"));
+
+ if (limSetLinkState(mac, eSIR_LINK_PRE_AUTH_REASSOC_STATE,
+ session_entry->bssId, session_entry->selfMacAddr,
+ NULL, NULL) != eSIR_SUCCESS) {
+ limLog(mac, LOGE,
+ FL("set link failed for eSIR_LINK_PRE_AUTH_REASSOC_STATE"));
+ lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL,
+ SIR_MBB_CONNECTED);
+ return;
+ }
+
+ /*
+ * Suspend link for same channel or different channel so that STA
+ * can be in power save for connected AP.
+ */
+ limLog(mac, LOG1,
+ FL("pre-auth on channel %d (session %p) currentOperChannel %d"),
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum,
+ session_entry, session_entry->currentOperChannel);
+ limSuspendLink(mac, eSIR_CHECK_ROAMING_SCAN,
+ pre_auth_mbb_suspend_link_handler,
+ (tANI_U32 *)session_entry);
+}
+
+
+/**
+ * lim_process_sta_mlm_del_sta_rsp_mbb() -Process del sta response
+ * @mac: MAC context
+ * @lim_msg: lim message
+ * @session_entry: session entry
+ *
+ * This function process del sta response
+ */
+void lim_process_sta_mlm_del_sta_rsp_mbb(tpAniSirGlobal mac,
+ tpSirMsgQ lim_msg, tpPESession session_entry)
+{
+ tpDeleteStaParams del_sta_params = (tpDeleteStaParams)lim_msg->bodyptr;
+ tpDphHashNode sta_ds = NULL;
+ tANI_U8 session_id;
+ tpPESession ft_session_entry;
+
+ if(NULL == del_sta_params) {
+ limLog(mac, LOGE, FL("Encountered NULL Pointer"));
+ goto end;
+ }
+
+ limLog(mac, LOG1, FL("Del STA RSP received. Status:%d AssocID:%d"),
+ del_sta_params->status, del_sta_params->assocId);
+
+ if (eHAL_STATUS_SUCCESS != del_sta_params->status) {
+ limLog(mac, LOGE, FL("Del STA failed! Status:%d, still proceeding"
+ "with Del BSS"), del_sta_params->status);
+ }
+
+ sta_ds = dphGetHashEntry(mac, DPH_STA_HASH_INDEX_PEER,
+ &session_entry->dph.dphHashTable);
+
+ if (sta_ds == NULL) {
+ limLog( mac, LOGE, FL("DPH Entry for STA %X missing"),
+ del_sta_params->assocId);
+ goto end;
+ }
+
+ if (eLIM_MLM_WT_DEL_STA_RSP_STATE != session_entry->limMlmState) {
+ limLog(mac, LOGE,
+ FL( "Received unexpected WDA_DELETE_STA_RSP in state %s" ),
+ limMlmStateStr(session_entry->limMlmState));
+ goto end;
+ }
+
+ limLog( mac, LOG1, FL("STA AssocID %d MAC "), sta_ds->assocId);
+ limPrintMacAddr(mac, sta_ds->staAddr, LOG1);
+
+ /*
+ * we must complete all cleanup related to del sta
+ * before calling del bss.
+ */
+ if (NULL != lim_msg->bodyptr) {
+ vos_mem_free(del_sta_params);
+ lim_msg->bodyptr = NULL;
+ }
+
+ /* Proceed to do del bss even if del sta resulted in failure */
+ lim_del_bss_mbb(mac, sta_ds, 0, session_entry);
+ return;
+
+end:
+ if(NULL != lim_msg->bodyptr) {
+ vos_mem_free(del_sta_params);
+ lim_msg->bodyptr = NULL;
+ }
+
+ /* Connected AP lim cleanup.*/
+ lim_cleanup_connected_ap(mac, sta_ds, session_entry);
+
+ ft_session_entry = peFindSessionByBssid(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId,
+ &session_id);
+ if (ft_session_entry == NULL) {
+ limLog(mac, LOGE,
+ FL("Unable to find session for the following bssid"));
+ limPrintMacAddr(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId, LOGE);
+ return;
+ }
+
+ /*
+ * eHAL_STATUS_INVALID_PARAMETER is used
+ * so that full cleanup is triggered.
+ */
+ lim_reassoc_fail_cleanup(mac, eHAL_STATUS_INVALID_PARAMETER,
+ (tANI_U32 *)ft_session_entry);
+}
+
+/**
+ * lim_cleanup_rx_path_mbb() -cleans up tspec related info
+ * @mac: MAC context
+ * @sta_ds: station entry
+ * @session_entry: session entry of connected AP
+ *
+ * This function cleans up tspec related info
+ */
+void lim_cleanup_rx_path_mbb(tpAniSirGlobal mac,
+ tpDphHashNode sta_ds,tpPESession session_entry)
+{
+ limLog(mac, LOG1, FL("AID %d limSmeState %d, mlmState %d"),
+ sta_ds->assocId, session_entry->limSmeState,
+ sta_ds->mlmStaContext.mlmState);
+
+ session_entry->isCiscoVendorAP = FALSE;
+
+ if (mac->lim.gLimAddtsSent)
+ tx_timer_deactivate(&mac->lim.limTimers.gLimAddtsRspTimer);
+
+ /* delete all tspecs associated with this sta. */
+ limAdmitControlDeleteSta(mac, sta_ds->assocId);
+}
+
+
+/**
+ * lim_cleanup_connected_ap() -cleans up connected AP lim info
+ * @mac: MAC context
+ * @sta_ds: station entry
+ * @session_entry: session entry of connected AP
+ *
+ * This function cleans up connected AP lim info
+ */
+void lim_cleanup_connected_ap(tpAniSirGlobal mac, tpDphHashNode sta_ds,
+ tpPESession session_entry)
+{
+ lim_cleanup_rx_path_mbb(mac, sta_ds, session_entry);
+ limDeleteDphHashEntry(mac, sta_ds->staAddr,
+ sta_ds->assocId, session_entry);
+
+ /**
+ * Make STA hash entry invalid at eCPU so that DPH
+ * does not process any more data packets and
+ * releases those BDs
+ */
+ sta_ds->valid = 0;
+
+ peDeleteSession(mac, session_entry);
+}
+
+/**
+ * lim_process_sta_mlm_del_bss_rsp_mbb() -Process del bss response of
+ * connected AP
+ * @mac: MAC context
+ * @lim_msg: lim message
+ * @session_entry: session entry of connected AP
+ *
+ * This function process del sta response
+ */
+void lim_process_sta_mlm_del_bss_rsp_mbb(tpAniSirGlobal mac,
+ tpSirMsgQ lim_msg, tpPESession session_entry)
+{
+ tpDeleteBssParams delbss_params = (tpDeleteBssParams)lim_msg->bodyptr;
+ tpDphHashNode sta_ds = dphGetHashEntry(mac, DPH_STA_HASH_INDEX_PEER,
+ &session_entry->dph.dphHashTable);
+ tpPESession ft_session_entry;
+ tANI_U8 session_id;
+
+ if (NULL == delbss_params) {
+ limLog(mac, LOGE, FL( "Invalid body pointer in message"));
+ goto end;
+ }
+
+ ft_session_entry = peFindSessionByBssid(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId,
+ &session_id);
+ if (ft_session_entry == NULL) {
+ limLog(mac, LOGE,
+ FL("Unable to find session for the following bssid"));
+ limPrintMacAddr(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId, LOGE);
+ goto end;
+ }
+
+ if(eHAL_STATUS_SUCCESS == delbss_params->status) {
+ limLog(mac, LOG1,
+ FL( "STA received the DEL_BSS_RSP for BSSID: %X."),
+ delbss_params->bssIdx);
+
+ if(sta_ds == NULL) {
+ limLog(mac, LOGE, FL("DPH Entry for STA missing"));
+ goto end;
+ }
+ if(eLIM_MLM_WT_DEL_BSS_RSP_STATE != session_entry->limMlmState) {
+ limLog(mac, LOGE,
+ FL("Received unexpected WDA_DEL_BSS_RSP in state %d"),
+ session_entry->limMlmState);
+ goto end;
+ }
+ limLog(mac, LOG1, FL("STA AssocID %d MAC "), sta_ds->assocId );
+ limPrintMacAddr(mac, sta_ds->staAddr, LOG1);
+
+ lim_cleanup_connected_ap(mac, sta_ds, session_entry);
+
+ lim_add_bss_mbb(mac, sta_ds, ft_session_entry);
+
+ if(NULL != lim_msg->bodyptr) {
+ vos_mem_free(delbss_params);
+ lim_msg->bodyptr = NULL;
+ }
+ return;
+ } else {
+ /*
+ * If del bss response is failure, cleanup sessions of both currently
+ * connected AP and roamable AP as add bss can not be send
+ * without successful delbss.
+ */
+ limLog(mac, LOGE,
+ FL("DEL BSS failed! Status:%d"), delbss_params->status);
+
+ if(NULL != lim_msg->bodyptr) {
+ vos_mem_free(delbss_params);
+ lim_msg->bodyptr = NULL;
+ }
+
+ /* Connected AP lim cleanup.*/
+ lim_cleanup_connected_ap(mac, sta_ds, session_entry);
+
+ /* Newly created session cleanup */
+ lim_reassoc_fail_cleanup(mac, eHAL_STATUS_MBB_DEL_BSS_FAIL,
+ (tANI_U32 *)ft_session_entry);
+ return;
+ }
+
+end:
+ if(NULL != lim_msg->bodyptr) {
+ vos_mem_free(delbss_params);
+ lim_msg->bodyptr = NULL;
+ }
+
+ lim_cleanup_connected_ap(mac, sta_ds, session_entry);
+
+ ft_session_entry = peFindSessionByBssid(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId,
+ &session_id);
+ if (ft_session_entry == NULL) {
+ limLog(mac, LOGE,
+ FL("Unable to find session for the following bssid"));
+ limPrintMacAddr(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId, LOGE);
+ return;
+ }
+
+ /*
+ * eHAL_STATUS_INVALID_PARAMETER is used
+ * so that full cleanup is triggered.
+ */
+ lim_reassoc_fail_cleanup(mac, eHAL_STATUS_INVALID_PARAMETER,
+ (tANI_U32 *)ft_session_entry);
+}
+
+
+void lim_fill_add_sta_params_mbb(tpAniSirGlobal mac,
+ tpPESession session_entry, tpAddStaParams add_sta_params)
+{
+ tANI_U32 listen_interval = WNI_CFG_LISTEN_INTERVAL_STADEF;
+ tANI_U32 self_sta_dot11_mode = 0;
+
+ vos_mem_copy(add_sta_params->staMac, session_entry->selfMacAddr,
+ sizeof(tSirMacAddr));
+ vos_mem_copy(add_sta_params->bssId, session_entry->bssId,
+ sizeof(tSirMacAddr));
+
+ add_sta_params->staType = STA_ENTRY_SELF;
+ add_sta_params->status = eHAL_STATUS_SUCCESS;
+ add_sta_params->respReqd = 1;
+
+ add_sta_params->sessionId = session_entry->peSessionId;
+ add_sta_params->staIdx = HAL_STA_INVALID_IDX;
+ add_sta_params->updateSta = FALSE;
+
+ add_sta_params->shortPreambleSupported =
+ session_entry->beaconParams.fShortPreamble;
+
+#ifdef WLAN_FEATURE_11AC
+ limPopulatePeerRateSet(mac, &add_sta_params->supportedRates, NULL,
+ false,session_entry, NULL);
+#else
+ limPopulatePeerRateSet(mac, &add_sta_params->supportedRates, NULL,
+ false,session_entry);
+#endif
+
+ if(session_entry->htCapability) {
+ add_sta_params->htCapable = session_entry->htCapability;
+#ifdef WLAN_FEATURE_11AC
+ add_sta_params->vhtCapable = session_entry->vhtCapability;
+ add_sta_params->vhtTxChannelWidthSet = session_entry->vhtTxChannelWidthSet;
+#endif
+
+#ifdef DISABLE_GF_FOR_INTEROP
+ if((session_entry->pLimJoinReq != NULL) &&
+ (!session_entry->pLimJoinReq->bssDescription.aniIndicator)) {
+ limLog(mac, LOGE,
+ FL("Turning off Greenfield, when adding self entry"));
+ add_sta_params->greenFieldCapable =
+ WNI_CFG_GREENFIELD_CAPABILITY_DISABLE;
+ }
+ else
+#endif
+ add_sta_params->greenFieldCapable =
+ limGetHTCapability( mac, eHT_GREENFIELD, session_entry);
+
+ if (session_entry->limRFBand == SIR_BAND_2_4_GHZ)
+ add_sta_params->txChannelWidthSet =
+ mac->roam.configParam.channelBondingMode24GHz;
+ else
+ add_sta_params->txChannelWidthSet =
+ mac->roam.configParam.channelBondingMode5GHz;
+
+ add_sta_params->mimoPS =
+ limGetHTCapability(mac, eHT_MIMO_POWER_SAVE, session_entry);
+ add_sta_params->rifsMode =
+ limGetHTCapability(mac, eHT_RIFS_MODE, session_entry);
+ add_sta_params->lsigTxopProtection =
+ limGetHTCapability(mac, eHT_LSIG_TXOP_PROTECTION, session_entry);
+ add_sta_params->delBASupport =
+ limGetHTCapability(mac, eHT_DELAYED_BA, session_entry);
+ add_sta_params->maxAmpduDensity =
+ limGetHTCapability(mac, eHT_MPDU_DENSITY, session_entry);
+ add_sta_params->maxAmpduSize =
+ limGetHTCapability(mac, eHT_MAX_RX_AMPDU_FACTOR, session_entry);
+ add_sta_params->maxAmsduSize =
+ limGetHTCapability(mac, eHT_MAX_AMSDU_LENGTH, session_entry);
+ add_sta_params->fDsssCckMode40Mhz =
+ limGetHTCapability(mac, eHT_DSSS_CCK_MODE_40MHZ, session_entry);
+ add_sta_params->fShortGI20Mhz =
+ limGetHTCapability(mac, eHT_SHORT_GI_20MHZ, session_entry);
+ add_sta_params->fShortGI40Mhz =
+ limGetHTCapability(mac, eHT_SHORT_GI_40MHZ, session_entry);
+ }
+
+ if (wlan_cfgGetInt(mac, WNI_CFG_LISTEN_INTERVAL,
+ &listen_interval) != eSIR_SUCCESS)
+ limLog(mac, LOGE, FL("Couldn't get LISTEN_INTERVAL"));
+
+ add_sta_params->listenInterval = (tANI_U16)listen_interval;
+
+ wlan_cfgGetInt(mac, WNI_CFG_DOT11_MODE, &self_sta_dot11_mode);
+ add_sta_params->supportedRates.opRateMode =
+ limGetStaRateMode((tANI_U8)self_sta_dot11_mode);
+
+ mac->ft.ftPEContext.pAddStaReq = add_sta_params;
+
+
+}
+
+void lim_process_sta_mlm_add_bss_rsp_mbb(tpAniSirGlobal mac,
+ tpSirMsgQ limMsgQ,tpPESession session_entry)
+{
+ tpAddBssParams add_bss_params = (tpAddBssParams)limMsgQ->bodyptr;
+ tpAddStaParams add_sta_params = NULL;
+ tpDphHashNode sta_ds = dphGetHashEntry(mac, DPH_STA_HASH_INDEX_PEER,
+ &session_entry->dph.dphHashTable);
+
+ if(add_bss_params == 0)
+ goto end;
+
+ limLog(mac, LOG1, FL("Add BSS RSP received. Status:%d"),
+ add_bss_params->status);
+
+ if(eHAL_STATUS_SUCCESS == add_bss_params->status) {
+
+ if(eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE != session_entry->limMlmState) {
+ limLog(mac, LOGE,
+ FL("Received unexpected ADD BSS in state %d"),
+ session_entry->limMlmState);
+ goto end;
+ }
+
+ session_entry->bssIdx = add_bss_params->bssIdx;
+
+ sta_ds->bssId = add_bss_params->bssIdx;
+ sta_ds->staIndex = add_bss_params->staContext.staIdx;
+ sta_ds->ucUcastSig = add_bss_params->staContext.ucUcastSig;
+ sta_ds->ucBcastSig = add_bss_params->staContext.ucBcastSig;
+
+ rrmCacheMgmtTxPower(mac, add_bss_params->txMgmtPower, session_entry);
+
+ /* Allocate memory for add sta params */
+ add_sta_params = vos_mem_malloc(sizeof( tAddStaParams ));
+ if (NULL == add_sta_params) {
+ limLog(mac, LOGE,
+ FL("Unable to allocate memory during ADD_STA"));
+ goto end;
+ }
+ vos_mem_set(add_sta_params, sizeof(tAddStaParams), 0);
+
+ /* Prepare add sta params */
+ lim_fill_add_sta_params_mbb(mac, session_entry, add_sta_params);
+
+ if(0 != limMsgQ->bodyptr) {
+ vos_mem_free(add_bss_params);
+ add_bss_params = NULL;
+ limMsgQ->bodyptr = NULL;
+ }
+
+ lim_add_sta_mbb(mac, session_entry->limAID, session_entry);
+
+ } else {
+ /*
+ * If add bss response is failure, cleanup session of roamable AP
+ * as cleanup of connected bss happened during del bss
+ */
+ limLog(mac, LOGE,
+ FL("ADD BSS failed! Status:%d"), add_bss_params->status);
+
+ /* Newly created session cleanup */
+ lim_reassoc_fail_cleanup(mac, eHAL_STATUS_MBB_ADD_BSS_FAIL,
+ (tANI_U32 *)session_entry);
+ }
+
+end:
+ if(0 != limMsgQ->bodyptr) {
+ vos_mem_free(add_bss_params);
+ add_bss_params = NULL;
+ limMsgQ->bodyptr = NULL;
+ }
+}
+
+/*
+ * lim_perform_post_add_sta_rsp() -invokes resume callback to handle add sta response
+ * @mac: MAC context
+ * @status: status
+ * @data: pointer to data
+ *
+ * This function invokes resume callback
+ */
+void lim_perform_post_add_sta_rsp(tpAniSirGlobal mac,
+ eHalStatus status, tANI_U32 *data)
+{
+ tpDphHashNode sta_ds;
+ /* session entry for newly roamed ap */
+ tpPESession session_entry;
+
+ session_entry = (tpPESession)data;
+
+ limLog(mac, LOG1, FL("forwarding cached packets"));
+ WLANTL_PreAssocForward(true);
+
+ sta_ds = dphGetHashEntry(mac, DPH_STA_HASH_INDEX_PEER,
+ &session_entry->dph.dphHashTable);
+ if(NULL != sta_ds)
+ sta_ds->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
+ else {
+ limLog(mac, LOGE,
+ FL("Unable to get the DPH Hash Entry for AID - %d"),
+ DPH_STA_HASH_INDEX_PEER);
+ return;
+ }
+
+ session_entry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
+ MTRACE(macTrace(mac, TRACE_CODE_MLM_STATE,
+ session_entry->peSessionId, eLIM_MLM_LINK_ESTABLISHED_STATE));
+
+#ifdef FEATURE_WLAN_TDLS
+ /* initialize TDLS peer related data */
+ limInitTdlsData(mac, session_entry);
+#endif
+
+ if (limSetLinkState(mac, eSIR_LINK_POSTASSOC_STATE, session_entry->bssId,
+ session_entry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS) {
+ limLog(mac, LOGE, FL("Set link state to POSTASSOC failed"));
+ return;
+ }
+
+ session_entry->limSmeState = eLIM_SME_LINK_EST_STATE;
+
+ lim_post_pre_auth_reassoc_rsp(mac, eSIR_SUCCESS, session_entry,
+ SIR_MBB_CONNECTED);
+
+ /* Freeup the cached preauth request */
+ if (mac->ft.ftPEContext.pFTPreAuthReq) {
+ limLog(mac, LOG1, FL("Freeing pFTPreAuthReq= %p"),
+ mac->ft.ftPEContext.pFTPreAuthReq);
+ if (mac->ft.ftPEContext.pFTPreAuthReq->pbssDescription) {
+ vos_mem_free(mac->ft.ftPEContext.pFTPreAuthReq->pbssDescription);
+ mac->ft.ftPEContext.pFTPreAuthReq->pbssDescription = NULL;
+ }
+ vos_mem_free(mac->ft.ftPEContext.pFTPreAuthReq);
+ mac->ft.ftPEContext.pFTPreAuthReq = NULL;
+ }
+}
+
+void lim_process_sta_mlm_add_sta_rsp_mbb(tpAniSirGlobal mac,
+ tpSirMsgQ limMsgQ,tpPESession session_entry)
+{
+ tpAddStaParams add_sta_params = (tpAddStaParams)limMsgQ->bodyptr;
+
+ if(NULL == add_sta_params) {
+ limLog(mac, LOGE, FL("Encountered NULL Pointer"));
+ return;
+ }
+
+ limLog(mac, LOG1, FL("Add STA RSP received. Status:%d"),
+ add_sta_params->status);
+
+ if (eHAL_STATUS_SUCCESS == add_sta_params->status) {
+ if ( eLIM_MLM_WT_ADD_STA_RSP_STATE != session_entry->limMlmState) {
+ limLog(mac, LOGE,
+ FL("Received unexpected ADD_STA_RSP in state %d"),
+ session_entry->limMlmState);
+ goto end;
+ }
+
+ /*
+ * Storing the self StaIndex(Generated by HAL) in session context,
+ * instead of storing it in DPH Hash entry for Self STA.
+ * DPH entry for the self STA stores the sta index for the BSS entry
+ * to which the STA is associated.
+ */
+ session_entry->staId = add_sta_params->staIdx;
+
+ limLog(mac, LOG1, FL("resuming to oper ch %d"),
+ session_entry->currentOperChannel);
+
+ peSetResumeChannel(mac, session_entry->currentOperChannel, 0);
+ limResumeLink(mac, lim_perform_post_add_sta_rsp, (tANI_U32 *)session_entry);
+ } else {
+ limLog(mac, LOGE, FL( "ADD_STA failed!"));
+
+ /* Newly created session cleanup */
+ lim_reassoc_fail_cleanup(mac, eHAL_STATUS_MBB_ADD_BSS_FAIL,
+ (tANI_U32 *)session_entry);
+
+ }
+end:
+ if( 0 != limMsgQ->bodyptr )
+ {
+ vos_mem_free(add_sta_params);
+ limMsgQ->bodyptr = NULL;
+ }
+}
+
+eAniBoolean lim_is_mbb_reassoc_in_progress(tpAniSirGlobal mac,
+ tpPESession session_entry)
+{
+ if (session_entry == NULL)
+ return eANI_BOOLEAN_FALSE;
+
+ if ((eLIM_STA_ROLE == session_entry->limSystemRole) &&
+ mac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+ limLog(mac, LOG1, FL("MBB Reassoc in progress"));
+ return eANI_BOOLEAN_TRUE;
+ }
+
+ return eANI_BOOLEAN_FALSE;
+}
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/pmm/pmmApi.c b/drivers/staging/prima/CORE/MAC/src/pe/pmm/pmmApi.c
index 21ac26cb2d7..1c31dc8ec3c 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/pmm/pmmApi.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/pmm/pmmApi.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -2176,14 +2176,22 @@ void pmmEnterWowlRequestHandler(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
goto end;
}
#endif
-
-
- if ((pMac->pmm.gPmmState != ePMM_STATE_BMPS_SLEEP) && (pMac->pmm.gPmmState != ePMM_STATE_WOWLAN))
+ /**
+ * In SAP mode BMPS is not supported skip bmps validation and
+ * send command directly.
+ */
+ if (pSessionEntry->operMode != BSS_OPERATIONAL_MODE_AP)
{
- pmmLog(pMac, LOGE, FL("Rcvd PMC_ENTER_WOWL_REQ in invalid Power Save state "));
- limSendSmeRsp(pMac, eWNI_PMC_ENTER_WOWL_RSP, eSIR_SME_INVALID_PMM_STATE, 0, 0);
- goto end;
- }
+ if ((pMac->pmm.gPmmState != ePMM_STATE_BMPS_SLEEP) &&
+ (pMac->pmm.gPmmState != ePMM_STATE_WOWLAN))
+ {
+ pmmLog(pMac, LOGE, FL("Rcvd PMC_ENTER_WOWL_REQ in invalid Power Save state "));
+ limSendSmeRsp(pMac, eWNI_PMC_ENTER_WOWL_RSP,
+ eSIR_SME_INVALID_PMM_STATE, 0, 0);
+ goto end;
+ }
+ } else
+ pmmLog(pMac,LOG1, FL("SAP dosn't support BMPS mode directly post wowl request"));
pHalWowlParams = vos_mem_malloc(sizeof(*pHalWowlParams));
if ( NULL == pHalWowlParams )
@@ -2363,6 +2371,7 @@ void pmmExitWowlanRequestHandler(tpAniSirGlobal pMac)
tpPESession pSessionEntry;
tpSirHalWowlExitParams pHalWowlMsg = NULL;
tANI_U8 PowersavesessionId = 0;
+ tANI_U8 smeSessionId = 0;
PowersavesessionId = pMac->pmm.sessionId;
@@ -2373,6 +2382,8 @@ void pmmExitWowlanRequestHandler(tpAniSirGlobal pMac)
goto failure;
}
+ smeSessionId = pSessionEntry->smeSessionId;
+
pHalWowlMsg = vos_mem_malloc(sizeof(*pHalWowlMsg));
if ( NULL == pHalWowlMsg )
{
@@ -2410,7 +2421,7 @@ void pmmExitWowlanRequestHandler(tpAniSirGlobal pMac)
failure:
if (pHalWowlMsg != NULL)
vos_mem_free(pHalWowlMsg);
- limSendSmeRsp(pMac, eWNI_PMC_EXIT_WOWL_RSP, smeRspCode, 0, 0);
+ limSendSmeRsp(pMac, eWNI_PMC_EXIT_WOWL_RSP, smeRspCode, smeSessionId, 0);
return;
}
@@ -2461,6 +2472,8 @@ void pmmExitWowlanResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
tpSirHalWowlExitParams pHalWowlRspMsg;
eHalStatus rspStatus = eHAL_STATUS_FAILURE;
+ tpPESession psessionEntry = NULL;
+ tANI_U8 smeSessionId = 0;
/* we need to process all the deferred messages enqueued
* since the initiating the WDA_WOWL_EXIT_REQ.
@@ -2477,17 +2490,23 @@ void pmmExitWowlanResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
// restore PMM state to BMPS mode
pMac->pmm.gPmmState = ePMM_STATE_BMPS_SLEEP;
rspStatus = pHalWowlRspMsg->status;
+ psessionEntry = peFindSessionByBssIdx(pMac, pHalWowlRspMsg->bssIdx);
+ if (psessionEntry) {
+ smeSessionId = psessionEntry->smeSessionId;
+ if (LIM_IS_AP_ROLE(psessionEntry))
+ pMac->pmm.gPmmState = ePMM_STATE_READY;
+ }
}
if( rspStatus == eHAL_STATUS_SUCCESS)
{
pmmLog(pMac, LOGW, FL("Rcvd successful rsp from HAL to exit WOWLAN "));
- limSendSmeRsp(pMac, eWNI_PMC_EXIT_WOWL_RSP, eSIR_SME_SUCCESS, 0, 0);
+ limSendSmeRsp(pMac, eWNI_PMC_EXIT_WOWL_RSP, eSIR_SME_SUCCESS, smeSessionId, 0);
}
else
{
pmmLog(pMac, LOGE, FL("Rcvd failure rsp from HAL to exit WOWLAN "));
- limSendSmeRsp(pMac, eWNI_PMC_EXIT_WOWL_RSP, eSIR_SME_WOWL_EXIT_REQ_FAILED, 0, 0);
+ limSendSmeRsp(pMac, eWNI_PMC_EXIT_WOWL_RSP, eSIR_SME_WOWL_EXIT_REQ_FAILED, smeSessionId, 0);
}
return;
}
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/sch/schBeaconGen.c b/drivers/staging/prima/CORE/MAC/src/pe/sch/schBeaconGen.c
index 0fc798995ae..15438a7796c 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/sch/schBeaconGen.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/sch/schBeaconGen.c
@@ -386,6 +386,13 @@ tSirRetStatus schSetFixedBeaconFields(tpAniSirGlobal pMac,tpPESession psessionEn
&pBcn2->WPA );
PopulateDot11fRSNOpaque( pMac, &psessionEntry->pLimStartBssReq->rsnIE,
&pBcn2->RSNOpaque );
+#ifdef SAP_AUTH_OFFLOAD
+ /* Software AP Authentication Offload feature
+ * only support WPA2-PSK AES and we
+ * need to update RSNIE for beacon
+ */
+ sap_auth_offload_update_rsn_ie(pMac, &pBcn2->RSNOpaque);
+#endif
}
if(psessionEntry->limWmeEnabled)
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/sch/schBeaconProcess.c b/drivers/staging/prima/CORE/MAC/src/pe/sch/schBeaconProcess.c
index 79f1ae8b0e6..7152d3be962 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/sch/schBeaconProcess.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/sch/schBeaconProcess.c
@@ -380,9 +380,14 @@ static void __schBeaconProcessForSession( tpAniSirGlobal pMac,
goto fail;
}
- if( RF_CHAN_14 >= psessionEntry->currentOperChannel )
+ if(RF_CHAN_14 >= psessionEntry->currentOperChannel)
{
- channelBondingMode = pMac->roam.configParam.channelBondingMode24GHz;
+ if (psessionEntry->force_24ghz_in_ht20)
+ channelBondingMode =
+ WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+ else
+ channelBondingMode =
+ pMac->roam.configParam.channelBondingMode24GHz;
}
else
{
diff --git a/drivers/staging/prima/CORE/SAP/inc/sapApi.h b/drivers/staging/prima/CORE/SAP/inc/sapApi.h
index dcb24828958..390e10b5d39 100644
--- a/drivers/staging/prima/CORE/SAP/inc/sapApi.h
+++ b/drivers/staging/prima/CORE/SAP/inc/sapApi.h
@@ -884,6 +884,30 @@ typedef VOS_STATUS (*tpWLAN_SAPEventCB)( tpSap_Event pSapEvent, v_PVOID_t pUsrC
v_U8_t WLANSAP_getState ( v_PVOID_t pvosGCtx);
/*==========================================================================
+ FUNCTION WLANSAP_get_sessionId
+
+ DESCRIPTION
+ This api returns the current SAP sessionId to the caller.
+
+ DEPENDENCIES
+
+ PARAMETERS
+
+ IN
+ pContext : Pointer to Sap Context structure
+ v_U8_t : Pointer to sessionID
+
+ RETURN VALUE
+ VOS_STATUS_SUCCESS on success.
+
+ VOS_STATUS_E_INVAL: Pointer to SAP cb is NULL ; access would cause a page
+ fault
+============================================================================*/
+VOS_STATUS WLANSAP_get_sessionId
+(
+ v_PVOID_t pvosGCtx, v_U8_t *sessionId
+);
+/*==========================================================================
FUNCTION WLANSAP_StartBss
DESCRIPTION
diff --git a/drivers/staging/prima/CORE/SAP/src/sapModule.c b/drivers/staging/prima/CORE/SAP/src/sapModule.c
index 5376ce60789..e8171b1782c 100644
--- a/drivers/staging/prima/CORE/SAP/src/sapModule.c
+++ b/drivers/staging/prima/CORE/SAP/src/sapModule.c
@@ -532,7 +532,52 @@ v_U8_t WLANSAP_getState
}
return pSapCtx->sapsMachine;
}
+/*==========================================================================
+ FUNCTION WLANSAP_get_sessionId
+
+ DESCRIPTION
+ This api returns the current SAP sessionId to the caller.
+
+ DEPENDENCIES
+
+ PARAMETERS
+
+ IN
+ pContext : Pointer to Sap Context structure
+ v_U8_t : Pointer to sessionID
+
+ RETURN VALUE
+ VOS_STATUS_SUCCESS on success.
+ VOS_STATUS_E_INVAL: Pointer to SAP cb is NULL ; access would cause a page
+ fault
+============================================================================*/
+VOS_STATUS WLANSAP_get_sessionId
+(
+ v_PVOID_t pvosGCtx, v_U8_t *sessionId
+)
+{
+ ptSapContext pSapCtx = NULL;
+ VOS_STATUS status = VOS_STATUS_SUCCESS;
+
+ pSapCtx = VOS_GET_SAP_CB(pvosGCtx);
+
+ if ( NULL == pSapCtx )
+ {
+ VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
+ "%s: Invalid SAP pointer from pvosGCtx", __func__);
+ status = VOS_STATUS_E_INVAL;
+ }
+
+ if (pSapCtx->sapsMachine == eSAP_STARTED) {
+ *sessionId = pSapCtx->sessionId;
+ status = VOS_STATUS_SUCCESS;
+ }
+ else
+ status = VOS_STATUS_E_FAILURE;
+
+ return status;
+}
/*==========================================================================
FUNCTION WLANSAP_StartBss
diff --git a/drivers/staging/prima/CORE/SME/inc/csrApi.h b/drivers/staging/prima/CORE/SME/inc/csrApi.h
index 3d6f28e80a5..715c7e6a24d 100644
--- a/drivers/staging/prima/CORE/SME/inc/csrApi.h
+++ b/drivers/staging/prima/CORE/SME/inc/csrApi.h
@@ -666,8 +666,6 @@ typedef enum
eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED,
// Participating in a Infra network and connected to a peer
eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED,
- /* Disconnecting with AP or stop connecting process */
- eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTING,
}eCsrConnectState;
@@ -959,6 +957,7 @@ typedef struct tagCsrRoamProfile
tCsrMobilityDomainInfo MDID;
#endif
tVOS_CON_MODE csrPersona;
+ bool force_24ghz_in_ht20;
tCsrBssid bssid_hint;
}tCsrRoamProfile;
@@ -1033,6 +1032,7 @@ typedef struct tagCsrNeighborRoamConfigParams
tANI_U16 nNeighborResultsRefreshPeriod;
tANI_U16 nEmptyScanRefreshPeriod;
tANI_U8 nNeighborInitialForcedRoamTo5GhEnable;
+ tANI_U8 nWeakZoneRssiThresholdForRoam;
}tCsrNeighborRoamConfigParams;
#endif
@@ -1199,6 +1199,11 @@ typedef struct tagCsrConfigParam
v_U32_t PERtimerThreshold;
v_U32_t PERroamTriggerPercent;
#endif
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ tANI_BOOLEAN enable_lfr_mbb;
+#endif
+
#endif
tANI_BOOLEAN ignorePeerErpInfo;
@@ -1239,6 +1244,7 @@ typedef struct tagCsrConfigParam
uint32_t edca_bk_aifs;
uint32_t edca_be_aifs;
tANI_BOOLEAN disable_scan_during_sco;
+ uint32_t sta_auth_retries_for_code17;
}tCsrConfigParam;
//Tush
@@ -1330,6 +1336,12 @@ typedef struct tagCsrRoamInfo
#ifdef WLAN_FEATURE_AP_HT40_24G
tpSirHT2040CoexInfoInd pSmeHT2040CoexInfoInd;
#endif
+ tDot11fIEHTCaps ht_caps;
+ tDot11fIEVHTCaps vht_caps;
+ tDot11fIEhs20vendor_ie hs20vendor_ie;
+ tDot11fIEVHTOperation vht_operation;
+ tDot11fIEHTInfo ht_operation;
+ bool reassoc;
}tCsrRoamInfo;
typedef struct tagCsrFreqScanInfo
@@ -1554,6 +1566,18 @@ struct tagCsrDelStaParams
u8 subtype;
};
+
+/**
+ * struct csr_set_tx_max_pwr_per_band - Req params to
+ * set max tx power per band
+ * @band: band for which power to be set
+ * @power: power to set in dB
+ */
+struct csr_set_tx_max_pwr_per_band {
+ eCsrBand band;
+ tPowerdBm power;
+};
+
////////////////////////////////////////////Common SCAN starts
//void *p2 -- the second context pass in for the caller
@@ -1754,6 +1778,5 @@ eHalStatus csrSetBand(tHalHandle hHal, eCsrBand eBand);
---------------------------------------------------------------------------*/
eCsrBand csrGetCurrentBand (tHalHandle hHal);
-
#endif
diff --git a/drivers/staging/prima/CORE/SME/inc/csrInternal.h b/drivers/staging/prima/CORE/SME/inc/csrInternal.h
index 2693992afa4..3d1fff6ac83 100644
--- a/drivers/staging/prima/CORE/SME/inc/csrInternal.h
+++ b/drivers/staging/prima/CORE/SME/inc/csrInternal.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -206,7 +206,7 @@ typedef enum
eCsrLostLink1Abort,
eCsrLostLink2Abort,
eCsrLostLink3Abort,
-
+ ecsr_mbb_perform_preauth_reassoc,
}eCsrRoamReason;
typedef enum
@@ -520,6 +520,7 @@ typedef struct tagCsrNeighborRoamConfig
tANI_U16 nNeighborResultsRefreshPeriod;
tANI_U16 nEmptyScanRefreshPeriod;
tANI_U8 nNeighborInitialForcedRoamTo5GhEnable;
+ tANI_U8 nWeakZoneRssiThresholdForRoam;
}tCsrNeighborRoamConfig;
#endif
@@ -636,6 +637,10 @@ typedef struct tagCsrConfig
#endif
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+ tANI_BOOLEAN enable_lfr_mbb;
+#endif
+
#ifdef FEATURE_WLAN_ESE
tANI_U8 isEseIniFeatureEnabled;
#endif
@@ -1495,3 +1500,18 @@ void csrDisableDfsChannel(tpAniSirGlobal pMac);
eHalStatus csrEnableRMC(tpAniSirGlobal pMac, tANI_U32 sessionId);
eHalStatus csrDisableRMC(tpAniSirGlobal pMac, tANI_U32 sessionId);
#endif /* WLAN_FEATURE_RMC */
+
+eHalStatus csrRoamStopNetwork(tpAniSirGlobal pMac, tANI_U32 sessionId,
+ tCsrRoamProfile *pProfile, tSirBssDescription *pBssDesc,
+ tDot11fBeaconIEs *pIes);
+
+eHalStatus csrRoamSaveSecurityRspIE(tpAniSirGlobal pMac,
+ tANI_U32 sessionId, eCsrAuthType authType,
+ tSirBssDescription *pSirBssDesc,
+ tDot11fBeaconIEs *pIes);
+
+void csrRoamSubstateChange(tpAniSirGlobal pMac,
+ eCsrRoamSubState NewSubstate, tANI_U32 sessionId);
+
+eHalStatus csrRoamFreeConnectedInfo(tpAniSirGlobal pMac,
+ tCsrRoamConnectedInfo *pConnectedInfo);
diff --git a/drivers/staging/prima/CORE/SME/inc/csrNeighborRoam.h b/drivers/staging/prima/CORE/SME/inc/csrNeighborRoam.h
index 5df4eee3d3d..93bfc0769ce 100644
--- a/drivers/staging/prima/CORE/SME/inc/csrNeighborRoam.h
+++ b/drivers/staging/prima/CORE/SME/inc/csrNeighborRoam.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2014, 2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2014, 2016-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -41,6 +41,12 @@
#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
#include "sme_Api.h"
+/* 15 seconds, for WPA, WPA2, CCKM */
+#define CSR_WAIT_FOR_KEY_TIMEOUT_PERIOD (15 * PAL_TIMER_TO_SEC_UNIT)
+/* 120 seconds, for WPS */
+#define CSR_WAIT_FOR_WPS_KEY_TIMEOUT_PERIOD (120 * PAL_TIMER_TO_SEC_UNIT)
+
+
/* Enumeration of various states in neighbor roam algorithm */
typedef enum
{
@@ -55,6 +61,10 @@ typedef enum
eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING,
eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE,
#endif /* WLAN_FEATURE_VOWIFI_11R */
+#ifdef WLAN_FEATURE_LFR_MBB
+ eCSR_NEIGHBOR_ROAM_STATE_MBB_PREAUTH_REASSOC,
+#endif
+
eNEIGHBOR_STATE_MAX
} eCsrNeighborRoamState;
@@ -71,6 +81,7 @@ typedef struct sCsrNeighborRoamCfgParams
tANI_U16 neighborResultsRefreshPeriod;
tANI_U16 emptyScanRefreshPeriod;
tANI_U8 neighborInitialForcedRoamTo5GhEnable;
+ tANI_U8 WeakZoneRssiThresholdForRoam;
} tCsrNeighborRoamCfgParams, *tpCsrNeighborRoamCfgParams;
#define CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX 255
@@ -206,6 +217,11 @@ typedef struct sCsrNeighborRoamControlInfo
vos_timer_t forcedInitialRoamTo5GHTimer;
tANI_U8 isForcedInitialRoamTo5GH;
tANI_U8 lastSentCmd;
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ bool is_pre_auth_reassoc_mbb_timer_started;
+#endif
+
} tCsrNeighborRoamControlInfo, *tpCsrNeighborRoamControlInfo;
@@ -251,6 +267,15 @@ VOS_STATUS csrNeighborRoamMergeChannelLists(tpAniSirGlobal pMac,
tANI_U8 *pOutputChannelList,
tANI_U8 outputNumOfChannels,
tANI_U8 *pMergedOutputNumOfChannels);
+tANI_BOOLEAN
+csrNeighborRoamRemoveRoamableAPListEntry(tpAniSirGlobal pMac,
+ tDblLinkList *pList, tpCsrNeighborRoamBSSInfo pNeighborEntry);
+eHalStatus
+csrNeighborRoamAddBssIdToPreauthFailList(tpAniSirGlobal pMac,
+ tSirMacAddr bssId);
+void csrNeighborRoamFreeNeighborRoamBSSNode(tpAniSirGlobal pMac,
+ tpCsrNeighborRoamBSSInfo neighborRoamBSSNode);
+
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
#define ROAM_SCAN_OFFLOAD_START 1
@@ -282,6 +307,10 @@ eHalStatus csrNeighborRoamHandoffReqHdlr(tpAniSirGlobal pMac, void* pMsg);
eHalStatus csrNeighborRoamProceedWithHandoffReq(tpAniSirGlobal pMac);
eHalStatus csrNeighborRoamSssidScanDone(tpAniSirGlobal pMac, eHalStatus status);
eHalStatus csrNeighborRoamStartLfrScan(tpAniSirGlobal pMac, tANI_U8 OffloadCmdStopReason);
+eHalStatus csrRoamStartWaitForKeyTimer(tpAniSirGlobal pMac,
+ tANI_U32 interval);
+void csrRoamLinkUp(tpAniSirGlobal pMac, tCsrBssid bssid);
+
#endif
#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
diff --git a/drivers/staging/prima/CORE/SME/inc/csr_roam_mbb.h b/drivers/staging/prima/CORE/SME/inc/csr_roam_mbb.h
new file mode 100644
index 00000000000..aa0bcbcaa97
--- /dev/null
+++ b/drivers/staging/prima/CORE/SME/inc/csr_roam_mbb.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+eHalStatus csr_neighbor_roam_issue_preauth_reassoc(tpAniSirGlobal mac);
+
+eHalStatus csr_roam_issue_preauth_reassoc_req(tHalHandle hal,
+ tANI_U32 session_id, tpSirBssDescription bss_description);
+
+void csr_roam_preauth_rsp_mbb_processor(tHalHandle hal,
+ tpSirFTPreAuthRsp pre_auth_rsp);
+
+void csr_preauth_reassoc_mbb_timer_callback(void *context);
+
+void csr_stop_preauth_reassoc_mbb_timer(tpAniSirGlobal mac);
+
diff --git a/drivers/staging/prima/CORE/SME/inc/pmc.h b/drivers/staging/prima/CORE/SME/inc/pmc.h
index e6ffe81d06a..cc15dc0b2ae 100644
--- a/drivers/staging/prima/CORE/SME/inc/pmc.h
+++ b/drivers/staging/prima/CORE/SME/inc/pmc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2013, 2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 2016-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -174,6 +174,7 @@ typedef struct sPmcInfo
tANI_BOOLEAN wowlEnabled; /* TRUE if WoWL is enabled */
tANI_BOOLEAN wowlModeRequired; /* TRUE if device should go to WOWL on entering BMPS */
tWowlExitSource wowlExitSrc; /*WoWl exiting because of wakeup pkt or user explicitly disabling WoWL*/
+ tANI_BOOLEAN isAPWOWExit; /* TRUE if last WOW exit is from soft ap */
void (*enterWowlCallbackRoutine) (void *callbackContext, eHalStatus status); /* routine to call for wowl request */
void *enterWowlCallbackContext;/* value to be passed as parameter to routine specified above */
tSirSmeWowlEnterParams wowlEnterParams; /* WOWL mode configuration */
diff --git a/drivers/staging/prima/CORE/SME/inc/smeInside.h b/drivers/staging/prima/CORE/SME/inc/smeInside.h
index bb947dc3ea2..902e0a0c6a3 100644
--- a/drivers/staging/prima/CORE/SME/inc/smeInside.h
+++ b/drivers/staging/prima/CORE/SME/inc/smeInside.h
@@ -207,6 +207,8 @@ typedef struct tagSmeCmd
tAniGetFrameLogReq getFramelogCmd;
struct s_ani_set_tx_max_pwr set_tx_max_pwr;
tpNanRequest pNanReq;
+ struct csr_set_tx_max_pwr_per_band set_tx_max_pwr_per_band;
+ tpSirUpdateChanList chan_list;
}u;
}tSmeCmd;
diff --git a/drivers/staging/prima/CORE/SME/inc/smeInternal.h b/drivers/staging/prima/CORE/SME/inc/smeInternal.h
index 3280a92dc2a..79f27af6ec2 100644
--- a/drivers/staging/prima/CORE/SME/inc/smeInternal.h
+++ b/drivers/staging/prima/CORE/SME/inc/smeInternal.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -76,6 +76,8 @@ typedef enum eSmeCommandType
eSmeCommandMacSpoofRequest,
eSmeCommandGetFrameLogRequest,
eSmeCommandSetMaxTxPower,
+ eSmeCommandSetMaxTxPowerPerBand,
+ eSmeCommandUpdateChannelList,
#ifdef FEATURE_WLAN_TDLS
//eSmeTdlsCommandMask = 0x80000, //To identify TDLS commands <TODO>
//These can be considered as csr commands.
@@ -187,7 +189,10 @@ typedef struct tagSmeStruct
void (*pOemDataIndCb) (void *, const tANI_U16, void *, tANI_U32);
void *pOemDataCallbackContext;
#endif /* FEATURE_OEM_DATA_SUPPORT */
-
+#ifdef WLAN_FEATURE_LFR_MBB
+ void (*roaming_mbb_callback)(void* mac, tANI_U32 session_id,
+ void* bss_description, void *reassoc_req, tANI_U32 csr_roam_op_code);
+#endif
} tSmeStruct, *tpSmeStruct;
diff --git a/drivers/staging/prima/CORE/SME/inc/sme_Api.h b/drivers/staging/prima/CORE/SME/inc/sme_Api.h
index 7039efc8666..5d4a8070b24 100644
--- a/drivers/staging/prima/CORE/SME/inc/sme_Api.h
+++ b/drivers/staging/prima/CORE/SME/inc/sme_Api.h
@@ -337,6 +337,15 @@ typedef enum
eSME_ROAM_TRIGGER_MAX
} tSmeFastRoamTrigger;
+#ifdef WLAN_FEATURE_APFIND
+struct sme_ap_find_request_req
+{
+ u_int16_t request_data_len;
+ const u_int8_t* request_data;
+};
+#endif /* WLAN_FEATURE_APFIND */
+
+
/*-------------------------------------------------------------------------
Function declarations and documentation.
------------------------------------------------------------------------*/
@@ -2722,15 +2731,19 @@ eHalStatus sme_p2pGetResultFilter(tHalHandle hHal, tANI_U8 HDDSessionId,
eHalStatus sme_SetMaxTxPower(tHalHandle hHal, tSirMacAddr pBssid,
tSirMacAddr pSelfMacAddress, v_S7_t dB);
-/* ---------------------------------------------------------------------------
- \fn sme_SetMaxTxPowerPerBand
- \brief Used to set the Maximum Transmit Power for
- specific band dynamically. Note: this setting will not persist over reboots
- \param band
- \param power to set in dB
- \- return eHalStatus
- -------------------------------------------------------------------------*/
-eHalStatus sme_SetMaxTxPowerPerBand(eCsrBand band, v_S7_t db);
+/**
+ * sme_SetMaxTxPowerPerBand() - Set the Maximum Transmit Power
+ * specific to band dynamically
+ * @band: Band for which power needs to be applied
+ * @dB: power to set in dB
+ * @hal: HAL handle
+ *
+ * Set the maximum transmit power dynamically per band
+ *
+ * Return: eHalStatus
+ */
+eHalStatus sme_SetMaxTxPowerPerBand(eCsrBand band, v_S7_t dB,
+ tHalHandle hal);
/* ---------------------------------------------------------------------------
@@ -3941,14 +3954,59 @@ void sme_set_mgmt_frm_via_wq5(tHalHandle hHal,
tANI_BOOLEAN sendMgmtPktViaWQ5);
eHalStatus sme_update_cfg_int_param(tHalHandle hHal, tANI_U32 cfg_id);
+#ifdef WLAN_FEATURE_APFIND
+VOS_STATUS sme_apfind_set_cmd(struct sme_ap_find_request_req *input);
+#endif /* WLAN_FEATURE_APFIND */
+
+#ifdef SAP_AUTH_OFFLOAD
+/**
+ * sme_set_sap_auth_offload() enable/disable SAP Auth Offload
+ * @hHal: hal layer handler
+ * @sap_auth_offload_info: the information of SAP Auth Offload
+ *
+ * This function provide enable/disable SAP authenticaiton offload
+ * feature on target firmware
+ *
+ * Return: eHalStatus.
+ */
+eHalStatus sme_set_sap_auth_offload(tHalHandle hHal,
+ struct tSirSapOffloadInfo *sap_auth_offload_info);
+
+#endif /* SAP_AUTH_OFFLOAD */
+#ifdef DHCP_SERVER_OFFLOAD
+eHalStatus sme_set_dhcp_srv_offload(tHalHandle hal,
+ sir_dhcp_srv_offload_info_t *dhcp_srv_info);
+#endif /* DHCP_SERVER_OFFLOAD */
+
+#ifdef MDNS_OFFLOAD
+eHalStatus sme_set_mdns_offload(tHalHandle hal,
+ sir_mdns_offload_info_t *mdns_info);
+
+eHalStatus sme_set_mdns_fqdn(tHalHandle hal,
+ sir_mdns_fqdn_info_t *mdns_fqdn);
+
+eHalStatus sme_set_mdns_resp(tHalHandle hal,
+ sir_mdns_resp_info_t *mdns_resp);
+#endif /* MDNS_OFFLOAD */
+
+eHalStatus sme_update_hb_threshold(tHalHandle hHal, tANI_U32 cfgId,
+ tANI_U8 hbThresh, eCsrBand eBand);
+
+eHalStatus sme_capture_tsf_req(tHalHandle hHal,
+ tSirCapTsfParams capTsfParams);
+
+eHalStatus sme_get_tsf_req(tHalHandle hHal,
+ tSirCapTsfParams capTsfParams);
+
+eHalStatus sme_set_tsfcb(tHalHandle hHal,
+ tsf_rsp_cb rsp_cb, struct stsf *pTsf,
+ void *pcallbackcontext);
+
/* ARP DEBUG STATS */
eHalStatus sme_set_nud_debug_stats(tHalHandle hHal,
psetArpStatsParams pSetStatsParam);
eHalStatus sme_get_nud_debug_stats(tHalHandle hHal,
pgetArpStatsParams pGetStatsParam);
-eHalStatus sme_test_con_alive(tHalHandle hHal);
-eHalStatus sme_get_con_alive(tHalHandle hHal,
- pgetConStatusParams conStatusParams);
-eHalStatus sme_test_con_delba(tHalHandle hHal, uint8_t sta_id,
- uint8_t session_id);
+eHalStatus sme_del_sta_ba_session_req(tHalHandle hHal,
+ tDelBaParams sta_del_params);
#endif //#if !defined( __SME_API_H )
diff --git a/drivers/staging/prima/CORE/SME/inc/sme_FTApi.h b/drivers/staging/prima/CORE/SME/inc/sme_FTApi.h
index 4eed9f51ce8..0a57aa5e8e0 100644
--- a/drivers/staging/prima/CORE/SME/inc/sme_FTApi.h
+++ b/drivers/staging/prima/CORE/SME/inc/sme_FTApi.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, 2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -72,6 +72,12 @@ typedef struct sFTSMEContext
tCsrRoamSetKey *pCsrFTKeyInfo;
v_BOOL_t addMDIE;
+
+ tANI_BOOLEAN is_preauth_lfr_mbb;
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ vos_timer_t pre_auth_reassoc_mbb_timer;
+#endif
} tftSMEContext, *tpftSMEContext;
/*--------------------------------------------------------------------------
diff --git a/drivers/staging/prima/CORE/SME/inc/sme_Trace.h b/drivers/staging/prima/CORE/SME/inc/sme_Trace.h
index 9967cacb260..77ff1d68903 100644
--- a/drivers/staging/prima/CORE/SME/inc/sme_Trace.h
+++ b/drivers/staging/prima/CORE/SME/inc/sme_Trace.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -146,6 +146,9 @@ enum {
TRACE_CODE_SME_RX_HDD_LPHB_CONFIG_REQ,
#endif /* FEATURE_WLAN_LPHB */
TRACE_CODE_SME_RX_HDD_ROAM_DEL_PMKIDCACHE,
+ TRACE_CODE_SME_TX_HDD_CAP_TSF_REQ,
+ TRACE_CODE_SME_TX_HDD_GET_TSF_REQ,
+ TRACE_CODE_SME_DEL_STA_BA_SESSION_REQ,
/* New trace commands to be added before this comment not at the end */
/* Trace codes for SME commands */
TRACE_CODE_SME_COMMAND = 250,
diff --git a/drivers/staging/prima/CORE/SME/src/csr/csrApiRoam.c b/drivers/staging/prima/CORE/SME/src/csr/csrApiRoam.c
index 47ccdef61f9..074fc3da612 100644
--- a/drivers/staging/prima/CORE/SME/src/csr/csrApiRoam.c
+++ b/drivers/staging/prima/CORE/SME/src/csr/csrApiRoam.c
@@ -76,14 +76,16 @@
#include "csrEse.h"
#endif /* FEATURE_WLAN_ESE && !FEATURE_WLAN_ESE_UPLOAD */
#include "vos_utils.h"
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "csr_roam_mbb.h"
+#endif
+
+
#define CSR_NUM_IBSS_START_CHANNELS_50 4
#define CSR_NUM_IBSS_START_CHANNELS_24 3
#define CSR_DEF_IBSS_START_CHANNEL_50 36
#define CSR_DEF_IBSS_START_CHANNEL_24 1
-/* 15 seconds, for WPA, WPA2, CCKM */
-#define CSR_WAIT_FOR_KEY_TIMEOUT_PERIOD (15 * PAL_TIMER_TO_SEC_UNIT)
-/* 120 seconds, for WPS */
-#define CSR_WAIT_FOR_WPS_KEY_TIMEOUT_PERIOD (120 * PAL_TIMER_TO_SEC_UNIT)
+
/*---------------------------------------------------------------------------
OBIWAN recommends [8 10]% : pick 9%
---------------------------------------------------------------------------*/
@@ -214,12 +216,10 @@ tANI_BOOLEAN csrRoamIsSameProfileKeys(tpAniSirGlobal pMac, tCsrRoamConnectedProf
static eHalStatus csrRoamStartRoamingTimer(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 interval);
static eHalStatus csrRoamStopRoamingTimer(tpAniSirGlobal pMac, tANI_U32 sessionId);
static void csrRoamRoamingTimerHandler(void *pv);
-eHalStatus csrRoamStartWaitForKeyTimer(tpAniSirGlobal pMac, tANI_U32 interval);
eHalStatus csrRoamStopWaitForKeyTimer(tpAniSirGlobal pMac);
static void csrRoamWaitForKeyTimeOutHandler(void *pv);
static eHalStatus CsrInit11dInfo(tpAniSirGlobal pMac, tCsr11dinfo *ps11dinfo);
static eHalStatus csrInitChannelPowerList( tpAniSirGlobal pMac, tCsr11dinfo *ps11dinfo);
-static eHalStatus csrRoamFreeConnectedInfo( tpAniSirGlobal pMac, tCsrRoamConnectedInfo *pConnectedInfo );
eHalStatus csrSendMBSetContextReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId,
tSirMacAddr peerMacAddr, tANI_U8 numKeys, tAniEdType edType,
tANI_BOOLEAN fUnicast, tAniKeyDirection aniKeyDirection,
@@ -230,7 +230,6 @@ static eHalStatus csrRoamIssueReassociate( tpAniSirGlobal pMac, tANI_U32 session
tCsrRoamProfile *pProfile );
void csrRoamStatisticsTimerHandler(void *pv);
void csrRoamStatsGlobalClassDTimerHandler(void *pv);
-static void csrRoamLinkUp(tpAniSirGlobal pMac, tCsrBssid bssid);
VOS_STATUS csrRoamVccTriggerRssiIndCallback(tHalHandle hHal,
v_U8_t rssiNotification,
void * context);
@@ -557,12 +556,13 @@ eHalStatus csrUpdateChannelList(tpAniSirGlobal pMac)
tCsrScanStruct *pScan = &pMac->scan;
tANI_U32 numChan = 0;
tANI_U32 bufLen ;
- vos_msg_t msg;
tANI_U8 i, j;
tANI_U8 num_channel = 0;
tANI_U8 channel_state;
tANI_U8 cfgnumChannels = 0;
tANI_U8 *cfgChannelList = NULL;
+ eHalStatus status;
+ tSmeCmd *command;
limInitOperatingClasses((tHalHandle)pMac);
numChan = sizeof(pMac->roam.validChannelList);
@@ -673,21 +673,28 @@ eHalStatus csrUpdateChannelList(tpAniSirGlobal pMac)
"%s : regID : %d \n", __func__,
pChanList->regId);
- msg.type = WDA_UPDATE_CHAN_LIST_REQ;
- msg.reserved = 0;
- msg.bodyptr = pChanList;
pChanList->numChan = num_channel;
- MTRACE(vos_trace(VOS_MODULE_ID_SME,
- TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, msg.type));
- if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))
- {
- VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,
- "%s: Failed to post msg to WDA", __func__);
- vos_mem_free(pChanList);
- return eHAL_STATUS_FAILURE;
+
+ status = sme_AcquireGlobalLock(&pMac->sme);
+ if (HAL_STATUS_SUCCESS(status)) {
+ command = csrGetCommandBuffer(pMac);
+ if (command) {
+ command->command = eSmeCommandUpdateChannelList;
+ command->u.chan_list = pChanList;
+
+ status = csrQueueSmeCommand(pMac, command, eANI_BOOLEAN_TRUE);
+ if (!HAL_STATUS_SUCCESS(status)) {
+ smsLog(pMac, LOGE, FL("fail to send msg status = %d"), status);
+ csrReleaseCommand(pMac, command);
+ }
+ } else {
+ smsLog(pMac, LOGE, FL("can not obtain a common buffer"));
+ status = eHAL_STATUS_RESOURCES;
+ }
+ sme_ReleaseGlobalLock(&pMac->sme);
}
- return eHAL_STATUS_SUCCESS;
+ return status;
}
eHalStatus csrStart(tpAniSirGlobal pMac)
@@ -753,7 +760,6 @@ eHalStatus csrStop(tpAniSirGlobal pMac, tHalStopType stopType)
(void) pmcDeregisterPowerSaveCheck(pMac, csrCheckPSReady);
//Reset the domain back to the deault
pMac->scan.domainIdCurrent = pMac->scan.domainIdDefault;
- csrResetCountryInformation(pMac, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_FALSE );
for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ )
{
@@ -1000,7 +1006,7 @@ eHalStatus csrRoamFreeConnectProfile(tpAniSirGlobal pMac, tCsrRoamConnectedProfi
return (status);
}
-static eHalStatus csrRoamFreeConnectedInfo( tpAniSirGlobal pMac, tCsrRoamConnectedInfo *pConnectedInfo )
+eHalStatus csrRoamFreeConnectedInfo( tpAniSirGlobal pMac, tCsrRoamConnectedInfo *pConnectedInfo )
{
eHalStatus status = eHAL_STATUS_SUCCESS;
if( pConnectedInfo->pbFrames )
@@ -1269,6 +1275,7 @@ static void initConfigParam(tpAniSirGlobal pMac)
pMac->roam.configParam.neighborRoamConfig.nNeighborResultsRefreshPeriod = 20000; //20 seconds
pMac->roam.configParam.neighborRoamConfig.nEmptyScanRefreshPeriod = 0;
pMac->roam.configParam.neighborRoamConfig.nNeighborInitialForcedRoamTo5GhEnable = 0;
+ pMac->roam.configParam.neighborRoamConfig.nWeakZoneRssiThresholdForRoam = 0;
#endif
#ifdef WLAN_FEATURE_11AC
pMac->roam.configParam.nVhtChannelWidth = WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ + 1;
@@ -1969,6 +1976,11 @@ eHalStatus csrChangeDefaultConfigParam(tpAniSirGlobal pMac, tCsrConfigParam *pPa
pParam->PERMinRssiThresholdForRoam;
pMac->PERroamTimeout = pParam->waitPeriodForNextPERScan;
#endif
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ pMac->roam.configParam.enable_lfr_mbb = pParam->enable_lfr_mbb;
+#endif
+
#ifdef FEATURE_WLAN_LFR
pMac->roam.configParam.isFastRoamIniFeatureEnabled = pParam->isFastRoamIniFeatureEnabled;
pMac->roam.configParam.MAWCEnabled = pParam->MAWCEnabled;
@@ -1989,6 +2001,7 @@ eHalStatus csrChangeDefaultConfigParam(tpAniSirGlobal pMac, tCsrConfigParam *pPa
smsLog( pMac, LOG1, "nNeighborResultsRefreshPeriod = %d", pMac->roam.configParam.neighborRoamConfig.nNeighborResultsRefreshPeriod);
smsLog( pMac, LOG1, "nEmptyScanRefreshPeriod = %d", pMac->roam.configParam.neighborRoamConfig.nEmptyScanRefreshPeriod);
smsLog( pMac, LOG1, "nNeighborInitialForcedRoamTo5GhEnable = %d", pMac->roam.configParam.neighborRoamConfig.nNeighborInitialForcedRoamTo5GhEnable);
+ smsLog( pMac, LOG1, "nWeakZoneRssiThresholdForRoam = %d", pMac->roam.configParam.neighborRoamConfig.nWeakZoneRssiThresholdForRoam);
{
int i;
smsLog( pMac, LOG1, FL("Num of Channels in CFG Channel List: %d"), pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels);
@@ -2199,6 +2212,11 @@ eHalStatus csrGetConfigParam(tpAniSirGlobal pMac, tCsrConfigParam *pParam)
pParam->PERMinRssiThresholdForRoam =
pMac->roam.configParam.PERMinRssiThresholdForRoam;
#endif
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ pParam->enable_lfr_mbb = pMac->roam.configParam.enable_lfr_mbb;
+#endif
+
#ifdef FEATURE_WLAN_LFR
pParam->isFastRoamIniFeatureEnabled = pMac->roam.configParam.isFastRoamIniFeatureEnabled;
#endif
@@ -3284,6 +3302,8 @@ eHalStatus csrRoamPrepareBssConfig(tpAniSirGlobal pMac, tCsrRoamProfile *pProfil
pBssConfig->uCfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
}
}
+ smsLog(pMac, LOG1, FL("phyMode %d uCfgDot11Mode %d"),
+ pProfile->phyMode, pBssConfig->uCfgDot11Mode);
//Qos
if ((pBssConfig->uCfgDot11Mode != eCSR_CFG_DOT11_MODE_11N) &&
(pMac->roam.configParam.WMMSupportMode == eCsrRoamWmmNoQos))
@@ -3364,6 +3384,12 @@ eHalStatus csrRoamPrepareBssConfig(tpAniSirGlobal pMac, tCsrRoamProfile *pProfil
}
//validate CB
pBssConfig->cbMode = csrGetCBModeFromIes(pMac, pBssDesc->channelId, pIes);
+ if (CSR_IS_CHANNEL_24GHZ(pBssDesc->channelId) &&
+ pProfile->force_24ghz_in_ht20) {
+ pBssConfig->cbMode = PHY_SINGLE_CHANNEL_CENTERED;
+ smsLog(pMac, LOG1,
+ FL("force_24ghz_in_ht20 is set so set cbmode to 0"));
+ }
smsLog(pMac, LOG1, FL("Bss Cb is %d, join timeout is %d, HB thresh is %d,"),
pBssConfig->cbMode, pBssConfig->uJoinTimeOut, pBssConfig->uHeartBeatThresh);
}while(0);
@@ -5057,6 +5083,20 @@ eHalStatus csrRoamProcessCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand )
pCommand->u.roamCmd.pLastRoamBss);
break;
+#ifdef WLAN_FEATURE_LFR_MBB
+ case ecsr_mbb_perform_preauth_reassoc:
+ smsLog(pMac, LOG1, FL("Attempting MBB PreAuth/Reassoc Req"));
+ status = csr_roam_issue_preauth_reassoc_req(pMac, sessionId,
+ pCommand->u.roamCmd.pLastRoamBss);
+ if (eHAL_STATUS_SUCCESS != status)
+ {
+ pMac->ft.ftSmeContext.is_preauth_lfr_mbb = false;
+ smsLog(pMac, LOG1, FL("is_preauth_lfr_mbb %d"),
+ pMac->ft.ftSmeContext.is_preauth_lfr_mbb);
+ }
+ break;
+#endif
+
default:
csrRoamStateChange( pMac, eCSR_ROAMING_STATE_JOINING, sessionId );
@@ -5194,9 +5234,10 @@ void csrResetBKIDCandidateList( tpAniSirGlobal pMac, tANI_U32 sessionId )
#endif /* FEATURE_WLAN_WAPI */
extern tANI_U8 csrWpaOui[][ CSR_WPA_OUI_SIZE ];
-static eHalStatus csrRoamSaveSecurityRspIE(tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrAuthType authType,
- tSirBssDescription *pSirBssDesc,
- tDot11fBeaconIEs *pIes)
+eHalStatus csrRoamSaveSecurityRspIE(tpAniSirGlobal pMac,
+ tANI_U32 sessionId, eCsrAuthType authType,
+ tSirBssDescription *pSirBssDesc,
+ tDot11fBeaconIEs *pIes)
{
eHalStatus status = eHAL_STATUS_SUCCESS;
tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
@@ -5610,10 +5651,12 @@ static tANI_BOOLEAN csrRoamProcessResults( tpAniSirGlobal pMac, tSmeCmd *pComman
case eCsrReassocSuccess:
if(eCsrReassocSuccess == Result)
{
+ roamInfo.reassoc = true;
ind_qos = SME_QOS_CSR_REASSOC_COMPLETE;
}
else
{
+ roamInfo.reassoc = false;
ind_qos = SME_QOS_CSR_ASSOC_COMPLETE;
}
// Success Join Response from LIM. Tell NDIS we are connected and save the
@@ -5819,6 +5862,12 @@ static tANI_BOOLEAN csrRoamProcessResults( tpAniSirGlobal pMac, tSmeCmd *pComman
roamInfo.ucastSig = ( tANI_U8 )pJoinRsp->ucastSig;
roamInfo.bcastSig = ( tANI_U8 )pJoinRsp->bcastSig;
roamInfo.maxRateFlags = pJoinRsp->maxRateFlags;
+ roamInfo.vht_caps = pJoinRsp->vht_caps;
+ roamInfo.ht_caps = pJoinRsp->ht_caps;
+ roamInfo.hs20vendor_ie = pJoinRsp->hs20vendor_ie;
+ roamInfo.ht_operation = pJoinRsp->ht_operation;
+ roamInfo.vht_operation = pJoinRsp->vht_operation;
+
}
else
{
@@ -6354,7 +6403,8 @@ static tANI_BOOLEAN csrRoamProcessResults( tpAniSirGlobal pMac, tSmeCmd *pComman
{
if ( CSR_IS_INFRA_AP(&pSession->connectedProfile) )
{
- roamInfo.u.pConnectedProfile = &pSession->connectedProfile;
+ roamInfo.u.pConnectedProfile =
+ &pSession->connectedProfile;
vos_mem_copy(roamInfo.peerMac,
pCommand->u.roamCmd.peerMac,
sizeof(tSirMacAddr));
@@ -6362,7 +6412,8 @@ static tANI_BOOLEAN csrRoamProcessResults( tpAniSirGlobal pMac, tSmeCmd *pComman
roamInfo.statusCode = eSIR_SME_SUCCESS;
status = csrRoamCallCallback(pMac, sessionId,
&roamInfo, pCommand->u.roamCmd.roamId,
- eCSR_ROAM_LOSTLINK, eCSR_ROAM_RESULT_FORCED);
+ eCSR_ROAM_LOSTLINK,
+ eCSR_ROAM_RESULT_FORCED);
}
}
else
@@ -6585,6 +6636,8 @@ eHalStatus csrRoamCopyProfile(tpAniSirGlobal pMac, tCsrRoamProfile *pDstProfile,
pDstProfile->cfg_protection = pSrcProfile->cfg_protection;
pDstProfile->wps_state = pSrcProfile->wps_state;
pDstProfile->ieee80211d = pSrcProfile->ieee80211d;
+ pDstProfile->force_24ghz_in_ht20 =
+ pSrcProfile->force_24ghz_in_ht20;
vos_mem_copy(&pDstProfile->Keys, &pSrcProfile->Keys,
sizeof(pDstProfile->Keys));
#ifdef WLAN_FEATURE_VOWIFI_11R
@@ -6989,19 +7042,7 @@ eHalStatus csrRoamConnect(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfi
#ifdef FEATURE_WLAN_BTAMP_UT_RF
pSession->maxRetryCount = CSR_JOIN_MAX_RETRY_COUNT;
#endif
- /*
- * If roamSession.connectState is disconnecting that mean
- * disconnect/stop adapter was received with scan for ssid
- * in progress and dropped. This state will ensure that
- * connect will not be issued from scan for ssid completion.
- * Thus if this fresh connect also issue scan for ssid the connect
- * command will be dropped assuming disconnect is in progress.
- * Thus reset connectState here
- */
- if (eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTING ==
- pMac->roam.roamSession[sessionId].connectState)
- pMac->roam.roamSession[sessionId].connectState =
- eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
+
if(CSR_INVALID_SCANRESULT_HANDLE != hBssListIn)
{
smsLog(pMac, LOG1, FL("is called with BSSList"));
@@ -7393,6 +7434,9 @@ eHalStatus csrRoamProcessDisassocDeauth( tpAniSirGlobal pMac, tSmeCmd *pCommand,
csrNeighborRoamTranistionPreauthDoneToDisconnected(pMac);
}
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+ csr_stop_preauth_reassoc_mbb_timer(pMac);
+#endif
}
if( fDisassoc )
@@ -7593,9 +7637,8 @@ eHalStatus csrRoamDisconnectInternal(tpAniSirGlobal pMac, tANI_U32 sessionId, eC
}
else
{
- pMac->roam.roamSession[sessionId].connectState =
- eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTING;
csrScanAbortScanForSSID(pMac, sessionId);
+ csrScanStartIdleScan(pMac);
status = eHAL_STATUS_CMD_NOT_QUEUED;
smsLog(pMac, LOGE,
FL("Disconnect not queued, Abort Scan for SSID"));
@@ -8181,6 +8224,12 @@ static void csrRoamingStateConfigCnfProcessor( tpAniSirGlobal pMac, tANI_U32 res
if(pCommand->u.roamCmd.pRoamBssEntry)
{
pScanResult = GET_BASE_ADDR(pCommand->u.roamCmd.pRoamBssEntry, tCsrScanResult, Link);
+ if (!pScanResult)
+ {
+ smsLog(pMac, LOGE,
+ FL("Failed to get base address for pScanResult"));
+ return;
+ }
pBssDesc = &pScanResult->Result.BssDescriptor;
}
if ( csrIsBssTypeIBSS( pCommand->u.roamCmd.roamProfile.BSSType ) ||
@@ -8208,6 +8257,12 @@ static void csrRoamingStateConfigCnfProcessor( tpAniSirGlobal pMac, tANI_U32 res
}
// If we are roaming TO an Infrastructure BSS...
VOS_ASSERT(pScanResult != NULL);
+ if( !pScanResult->Result.pvIes )
+ {
+ smsLog(pMac, LOGE, FL(" pvIes is NULL"));
+ return;
+ }
+
if ( csrIsInfraBssDesc( pBssDesc ) )
{
tDot11fBeaconIEs *pIesLocal = (tDot11fBeaconIEs *)pScanResult->Result.pvIes;
@@ -9952,6 +10007,15 @@ void csrRoamCheckForLinkStatusChange( tpAniSirGlobal pMac, tSirSmeRsp *pSirMsg )
status = csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_WDS_IND, eCSR_ROAM_RESULT_WDS_ASSOCIATION_IND);//Sta
if(CSR_IS_INFRA_AP(pRoamInfo->u.pConnectedProfile))
{
+#ifdef SAP_AUTH_OFFLOAD
+ if (pMac->sap_auth_offload)
+ {
+ smsLog(pMac, LOGW, FL(" Auth is not required to set in Auth offload case \n"));
+ pRoamInfo->fAuthRequired = FALSE;
+ }
+ else
+ {
+#endif
if( CSR_IS_ENC_TYPE_STATIC( pSession->pCurRoamProfile->negotiatedUCEncryptionType ))
{
csrRoamIssueSetContextReq( pMac, sessionId, pSession->pCurRoamProfile->negotiatedUCEncryptionType,
@@ -9964,6 +10028,9 @@ void csrRoamCheckForLinkStatusChange( tpAniSirGlobal pMac, tSirSmeRsp *pSirMsg )
{
pRoamInfo->fAuthRequired = TRUE;
}
+#ifdef SAP_AUTH_OFFLOAD
+ }
+#endif
status = csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_INFRA_IND, eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND);
if (!HAL_STATUS_SUCCESS(status))
pRoamInfo->statusCode = eSIR_SME_ASSOC_REFUSED;// Refused due to Mac filtering
@@ -10028,6 +10095,10 @@ void csrRoamCheckForLinkStatusChange( tpAniSirGlobal pMac, tSirSmeRsp *pSirMsg )
csrNeighborRoamTranistionPreauthDoneToDisconnected(pMac);
}
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+ csr_stop_preauth_reassoc_mbb_timer(pMac);
+#endif
+
pSession = CSR_GET_SESSION( pMac, sessionId );
if (!pSession)
@@ -10104,6 +10175,9 @@ void csrRoamCheckForLinkStatusChange( tpAniSirGlobal pMac, tSirSmeRsp *pSirMsg )
csrNeighborRoamTranistionPreauthDoneToDisconnected(pMac);
}
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+ csr_stop_preauth_reassoc_mbb_timer(pMac);
+#endif
pSession = CSR_GET_SESSION( pMac, sessionId );
if(!pSession)
@@ -10683,6 +10757,12 @@ void csrRoamCheckForLinkStatusChange( tpAniSirGlobal pMac, tSirSmeRsp *pSirMsg )
{
tpSirSetActiveModeSetBncFilterReq pMsg;
pMsg = vos_mem_malloc(sizeof(tSirSetActiveModeSetBncFilterReq));
+ if (NULL == pMsg)
+ {
+ smsLog(pMac, LOGE, FL("vos_mem_malloc failed"));
+ return;
+ }
+
pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_SET_BCN_FILTER_REQ);
pMsg->length = pal_cpu_to_be16(sizeof(
tSirSetActiveModeSetBncFilterReq));
@@ -10706,6 +10786,12 @@ void csrRoamCheckForLinkStatusChange( tpAniSirGlobal pMac, tSirSmeRsp *pSirMsg )
{
tpSirSmeHT40OBSSScanInd pMsg;
pMsg = vos_mem_malloc(sizeof(tSirSmeHT40OBSSScanInd));
+ if (NULL == pMsg)
+ {
+ smsLog(pMac, LOGE, FL("vos_mem_malloc failed"));
+ return;
+ }
+
pMsg->messageType =
pal_cpu_to_be16((tANI_U16)eWNI_SME_HT40_OBSS_SCAN_IND);
pMsg->length =
@@ -10884,6 +10970,13 @@ void csrRoamCheckForLinkStatusChange( tpAniSirGlobal pMac, tSirSmeRsp *pSirMsg )
csrRoamFTPreAuthRspProcessor( pMac, (tpSirFTPreAuthRsp)pSirMsg );
break;
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+ case eWNI_SME_MBB_PRE_AUTH_REASSOC_RSP:
+ csr_roam_preauth_rsp_mbb_processor(pMac,
+ (tpSirFTPreAuthRsp)pSirMsg);
+ break;
+#endif
+
case eWNI_SME_MAX_ASSOC_EXCEEDED:
pSmeMaxAssocInd = (tSmeMaxAssocInd*)pSirMsg;
smsLog( pMac, LOG1, FL("send indication that max assoc have been reached and the new peer cannot be accepted"));
@@ -11105,35 +11198,35 @@ void csrRoamWaitForKeyTimeOutHandler(void *pv)
macTraceGetcsrRoamSubState(
pMac->roam.curSubState[pInfo->sessionId]));
- if( CSR_IS_WAIT_FOR_KEY( pMac, pInfo->sessionId ) )
+ if (pSession)
{
-#ifdef FEATURE_WLAN_LFR
- if (csrNeighborRoamIsHandoffInProgress(pMac))
+ if( CSR_IS_WAIT_FOR_KEY( pMac, pInfo->sessionId ) )
{
- /*
- * Enable heartbeat timer when hand-off is in progress
- * and Key Wait timer expired.
- */
- smsLog(pMac, LOG2, "Enabling HB timer after WaitKey expiry"
- " (nHBCount=%d)",
- pMac->roam.configParam.HeartbeatThresh24);
- ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD,
- pMac->roam.configParam.HeartbeatThresh24,
- NULL, eANI_BOOLEAN_FALSE);
- }
+#ifdef FEATURE_WLAN_LFR
+ if (csrNeighborRoamIsHandoffInProgress(pMac))
+ {
+ /*
+ * Enable heartbeat timer when hand-off is in progress
+ * and Key Wait timer expired.
+ */
+ smsLog(pMac, LOG2, "Enabling HB timer after WaitKey expiry"
+ " (nHBCount=%d)",
+ pMac->roam.configParam.HeartbeatThresh24);
+ ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD,
+ pMac->roam.configParam.HeartbeatThresh24,
+ NULL, eANI_BOOLEAN_FALSE);
+ }
#endif
- smsLog(pMac, LOGE, " SME pre-auth state timeout. ");
+ smsLog(pMac, LOGE, " SME pre-auth state timeout. ");
- //Change the substate so command queue is unblocked.
- if (CSR_ROAM_SESSION_MAX > pInfo->sessionId)
- {
- csrRoamSubstateChange(pMac, eCSR_ROAM_SUBSTATE_NONE,
- pInfo->sessionId);
- }
+ //Change the substate so command queue is unblocked.
+ if (CSR_ROAM_SESSION_MAX > pInfo->sessionId)
+ {
+ csrRoamSubstateChange(pMac, eCSR_ROAM_SUBSTATE_NONE,
+ pInfo->sessionId);
+ }
- if (pSession)
- {
- if( csrIsConnStateConnectedInfra(pMac, pInfo->sessionId) )
+ if( csrIsConnStateConnectedInfra(pMac, pInfo->sessionId) )
{
csrRoamLinkUp(pMac, pSession->connectedProfile.bssid);
smeProcessPendingQueue(pMac);
@@ -11691,7 +11784,13 @@ static eCsrCfgDot11Mode csrRoamGetPhyModeBandForBss( tpAniSirGlobal pMac, tCsrRo
}
/* Incase of WEP Security encryption type is coming as part of add key. So while STart BSS dont have information */
- if( (!CSR_IS_11n_ALLOWED(pProfile->EncryptionType.encryptionType[0] ) || ((pProfile->privacy == 1) && (pProfile->EncryptionType.encryptionType[0] == eCSR_ENCRYPT_TYPE_NONE)) ) &&
+ if (
+#ifdef SAP_AUTH_OFFLOAD
+ (!pMac->sap_auth_offload && !pMac->sap_auth_offload_sec_type) &&
+#endif
+ ((!CSR_IS_11n_ALLOWED(pProfile->EncryptionType.encryptionType[0] ) ||
+ ((pProfile->privacy == 1) &&
+ (pProfile->EncryptionType.encryptionType[0] == eCSR_ENCRYPT_TYPE_NONE)))) &&
((eCSR_CFG_DOT11_MODE_11N == cfgDot11Mode) ||
#ifdef WLAN_FEATURE_11AC
(eCSR_CFG_DOT11_MODE_11AC == cfgDot11Mode) ||
@@ -13397,6 +13496,9 @@ eHalStatus csrSendJoinReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirBssDe
//Need to disable VHT operation in 2.4 GHz band
ucDot11Mode = WNI_CFG_DOT11_MODE_11N;
}
+ smsLog(pMac, LOG1, FL("dot11mode %d uCfgDot11Mode %d"),
+ ucDot11Mode, pSession->bssParams.uCfgDot11Mode);
+
*pBuf = (tANI_U8)ucDot11Mode;
pBuf++;
//Persona
@@ -13409,9 +13511,13 @@ eHalStatus csrSendJoinReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirBssDe
//CBMode
*pBuf = (tANI_U8)pSession->bssParams.cbMode;
pBuf++;
+ *pBuf = (tANI_U8)pProfile->force_24ghz_in_ht20;
+ pBuf++;
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
- FL("CSR PERSONA=%d CSR CbMode %d"), pProfile->csrPersona, pSession->bssParams.cbMode);
+ FL("CSR PERSONA=%d CSR CbMode %d force_24ghz_in_ht20 %d"),
+ pProfile->csrPersona, pSession->bssParams.cbMode,
+ pProfile->force_24ghz_in_ht20);
// uapsdPerAcBitmask
*pBuf = pProfile->uapsd_mask;
@@ -13968,6 +14074,719 @@ eHalStatus csrSendJoinReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirBssDe
return( status );
}
+#ifdef WLAN_FEATURE_LFR_MBB
+/**
+ * csr_prepare_reassoc_req () - Prepares reassoc request
+ * @mac: MAC context
+ * @session_id: session id
+ * @pbss_description: bss description
+ * @ies: pointer to beacon IE's
+ * @reassoc_req: pointer to reassociation request
+ *
+ *Return: None
+ */
+eHalStatus csr_fill_reassoc_req(tpAniSirGlobal mac, tANI_U32 session_id,
+ tSirBssDescription *bss_description, tDot11fBeaconIEs *ies,
+ tSirSmeJoinReq **reassoc_req)
+{
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ tSirSmeJoinReq *csr_join_req;
+ tANI_U8 *buf;
+ v_U8_t acm_mask = 0, uapsd_mask;
+ tANI_U16 msg_len, w_tmp, ie_len;
+ tSirMacRateSet op_rate_set;
+ tSirMacRateSet ex_rate_set;
+ tCsrRoamSession *session = CSR_GET_SESSION(mac, session_id);
+ tANI_U32 dw_tmp;
+ tANI_U8 wpa_rsn_ie[DOT11F_IE_RSN_MAX_LEN];
+ tANI_U32 uc_dot11_mode = 0;
+ tANI_U8 tx_bf_csn_value = 0;
+ tANI_U16 rate_bitmap = 0;
+ tANI_U16 message_type = eWNI_SME_REASSOC_REQ;
+ tCsrRoamProfile *profile;
+
+ if(!session) {
+ smsLog(mac, LOGE, FL(" session %d not found "), session_id);
+ return eHAL_STATUS_FAILURE;
+ }
+
+ if (NULL == bss_description) {
+ smsLog(mac, LOGE, FL(" pBssDescription is NULL"));
+ return eHAL_STATUS_FAILURE;
+ }
+
+ smsLog(mac, LOG1,
+ FL("session_id %d"), session_id);
+
+ profile = vos_mem_malloc(sizeof(*profile));
+ if (NULL == profile) {
+ smsLog(mac, LOGE, FL("Memory allocation failure for profile"));
+ return eHAL_STATUS_RESOURCES;
+ }
+
+ status = csrRoamCopyProfile(mac, profile, session->pCurRoamProfile);
+ if(!HAL_STATUS_SUCCESS(status)) {
+ smsLog(mac, LOGE, FL("Profile copy failed"));
+ return eHAL_STATUS_FAILURE;
+ }
+
+ do {
+ /*
+ * There are a number of variable length fields to consider.
+ * First, the tSirSmeJoinReq includes a single bssDescription.
+ * bssDescription includes a single tANI_U32 for the IE fields,
+ * but the length field in the bssDescription needs to be
+ * interpreted to determine length of the IE fields.
+ * So, take the size of the JoinReq, subtract the size of the
+ * bssDescription and add in the length from the bssDescription
+ * (then add the size of the 'length' field itself because that is
+ * NOT included in the length field). msgLen =
+ * sizeof( tSirSmeJoinReq ) - sizeof( *pBssDescription ) +
+ * pBssDescription->length + sizeof( pBssDescription->length ) +
+ * sizeof( tCsrWpaIe ) + sizeof( tCsrWpaAuthIe ) + sizeof( tANI_U16 );
+ * add in the size of the WPA IE that we may build.
+ */
+
+ msg_len = sizeof(tSirSmeJoinReq) - sizeof(*bss_description) +
+ bss_description->length + sizeof(bss_description->length) +
+ sizeof(tCsrWpaIe) + sizeof(tCsrWpaAuthIe) + sizeof(tANI_U16);
+
+ csr_join_req = vos_mem_malloc(msg_len);
+ if (NULL == csr_join_req)
+ status = eHAL_STATUS_FAILURE;
+ else
+ status = eHAL_STATUS_SUCCESS;
+ if (!HAL_STATUS_SUCCESS(status)) break;
+
+ vos_mem_set(csr_join_req, msg_len, 0);
+ *reassoc_req = csr_join_req;
+
+ csr_join_req->messageType = pal_cpu_to_be16(eWNI_SME_REASSOC_REQ);
+ csr_join_req->length = pal_cpu_to_be16(msg_len);
+ buf = &csr_join_req->sessionId;
+
+ /* session_id */
+ *buf = (tANI_U8)session_id;
+ buf++;
+
+ /* transactionId */
+ *buf = 0;
+ *(buf + 1) = 0;
+ buf += sizeof(tANI_U16);
+
+ /* ssId */
+ if(ies->SSID.present && ies->SSID.num_ssid)
+ {
+ /* ssId len */
+ *buf = ies->SSID.num_ssid;
+ buf++;
+ vos_mem_copy(buf, ies->SSID.ssid, ies->SSID.num_ssid);
+ buf += ies->SSID.num_ssid;
+ }
+ else
+ {
+ *buf = 0;
+ buf++;
+ }
+
+ /* selfMacAddr */
+ vos_mem_copy((tSirMacAddr *)buf, &session->selfMacAddr,
+ sizeof(tSirMacAddr));
+ buf += sizeof(tSirMacAddr);
+
+ /* bsstype */
+ dw_tmp =
+ pal_cpu_to_be32(csrTranslateBsstypeToMacType(profile->BSSType));
+ /* Override BssType for BTAMP */
+ if (dw_tmp == eSIR_BTAMP_STA_MODE) dw_tmp = eSIR_BTAMP_AP_MODE;
+ vos_mem_copy(buf, &dw_tmp, sizeof(tSirBssType));
+ buf += sizeof(tSirBssType);
+
+ /* dot11mode */
+ uc_dot11_mode =
+ csrTranslateToWNICfgDot11Mode(mac, session->bssParams.uCfgDot11Mode);
+ if (bss_description->channelId <= 14 &&
+ FALSE == mac->roam.configParam.enableVhtFor24GHz &&
+ WNI_CFG_DOT11_MODE_11AC == uc_dot11_mode)
+ {
+ /* Need to disable VHT operation in 2.4 GHz band */
+ uc_dot11_mode = WNI_CFG_DOT11_MODE_11N;
+ }
+ *buf = (tANI_U8)uc_dot11_mode;
+ buf++;
+
+ /* Persona */
+ *buf = (tANI_U8)profile->csrPersona;
+ buf++;
+ *buf = (tANI_U8)profile->bOSENAssociation;
+ buf++;
+ *buf = (tANI_U8)profile->bWPSAssociation;
+ buf++;
+
+ /* CBMode */
+ *buf = (tANI_U8)session->bssParams.cbMode;
+ buf++;
+
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
+ FL("CSR PERSONA=%d CSR CbMode %d"), profile->csrPersona,
+ session->bssParams.cbMode);
+
+ /* uapsdPerAcBitmask */
+ *buf = profile->uapsd_mask;
+ buf++;
+
+
+ status = csrGetRateSet(mac, profile, (eCsrPhyMode)profile->phyMode,
+ bss_description, ies, &op_rate_set, &ex_rate_set,&rate_bitmap);
+ if (HAL_STATUS_SUCCESS(status))
+ {
+ /* OperationalRateSet */
+ if (op_rate_set.numRates) {
+ *buf++ = op_rate_set.numRates;
+ vos_mem_copy(buf, op_rate_set.rate, op_rate_set.numRates);
+ buf += op_rate_set.numRates;
+ } else *buf++ = 0;
+
+ /* ExtendedRateSet */
+ if (ex_rate_set.numRates) {
+ *buf++ = ex_rate_set.numRates;
+ vos_mem_copy(buf, ex_rate_set.rate, ex_rate_set.numRates);
+ buf += ex_rate_set.numRates;
+ } else *buf++ = 0;
+ }
+ else
+ {
+ *buf++ = 0;
+ *buf++ = 0;
+ }
+
+ /* rateBitmap */
+ vos_mem_copy(buf, &rate_bitmap, sizeof(tANI_U16));
+ buf += sizeof(tANI_U16);
+
+ profile->negotiatedAuthType =
+ mac->roam.roamSession[session_id].connectedProfile.AuthType;
+ profile->negotiatedUCEncryptionType =
+ mac->roam.roamSession[session_id].connectedProfile.EncryptionType;
+
+ /* rsnIE */
+ if ( csrIsProfileWpa(profile))
+ {
+ /* Insert the Wpa IE into the join request */
+ ie_len = csrRetrieveWpaIe(mac, profile, bss_description, ies,
+ (tCsrWpaIe *)(wpa_rsn_ie));
+ }
+ else if( csrIsProfileRSN(profile))
+ {
+ /* Insert the RSN IE into the join request */
+ ie_len = csrRetrieveRsnIe(mac, session_id, profile, bss_description,
+ ies, (tCsrRSNIe *)(wpa_rsn_ie));
+ }
+#ifdef FEATURE_WLAN_WAPI
+ else if( csrIsProfileWapi(profile))
+ {
+ /* Insert the WAPI IE into the join request */
+ ie_len = csrRetrieveWapiIe(mac, session_id, profile,
+ bss_description, ies, (tCsrWapiIe *)(wpa_rsn_ie));
+ }
+#endif
+ else
+ {
+ ie_len = 0;
+ }
+ /* remember the IE for future use */
+ if(ie_len)
+ {
+ if(ie_len > DOT11F_IE_RSN_MAX_LEN)
+ {
+ smsLog(mac, LOGE,
+ FL("WPA RSN IE length :%d is more than RSN_MAX_LEN %d"),
+ ie_len, DOT11F_IE_RSN_MAX_LEN);
+ ie_len = DOT11F_IE_RSN_MAX_LEN;
+ }
+#ifdef FEATURE_WLAN_WAPI
+ if( csrIsProfileWapi(profile))
+ {
+ /* Check whether we need to allocate more memory */
+ if(ie_len > session->nWapiReqIeLength)
+ {
+ if(session->pWapiReqIE && session->nWapiReqIeLength)
+ {
+ vos_mem_free(session->pWapiReqIE);
+ }
+ session->pWapiReqIE = vos_mem_malloc(ie_len);
+ if (NULL == session->pWapiReqIE)
+ status = eHAL_STATUS_FAILURE;
+ else
+ status = eHAL_STATUS_SUCCESS;
+ if(!HAL_STATUS_SUCCESS(status)) break;
+ }
+ session->nWapiReqIeLength = ie_len;
+ vos_mem_copy(session->pWapiReqIE, wpa_rsn_ie, ie_len);
+ w_tmp = pal_cpu_to_be16(ie_len);
+ vos_mem_copy(buf, &w_tmp, sizeof(tANI_U16));
+ buf += sizeof(tANI_U16);
+ vos_mem_copy(buf, wpa_rsn_ie, ie_len);
+ buf += ie_len;
+ }
+ else /* should be WPA/WPA2 otherwise */
+#endif
+ {
+ /* Check whether we need to allocate more memory */
+ if(ie_len > session->nWpaRsnReqIeLength)
+ {
+ if(session->pWpaRsnReqIE && session->nWpaRsnReqIeLength)
+ {
+ vos_mem_free(session->pWpaRsnReqIE);
+ }
+ session->pWpaRsnReqIE = vos_mem_malloc(ie_len);
+ if (NULL == session->pWpaRsnReqIE)
+ status = eHAL_STATUS_FAILURE;
+ else
+ status = eHAL_STATUS_SUCCESS;
+ if(!HAL_STATUS_SUCCESS(status)) break;
+ }
+ session->nWpaRsnReqIeLength = ie_len;
+ vos_mem_copy(session->pWpaRsnReqIE, wpa_rsn_ie, ie_len);
+ w_tmp = pal_cpu_to_be16(ie_len);
+ vos_mem_copy(buf, &w_tmp, sizeof(tANI_U16));
+ buf += sizeof(tANI_U16);
+ vos_mem_copy(buf, wpa_rsn_ie, ie_len);
+ buf += ie_len;
+ }
+ }
+ else
+ {
+ /* free whatever old info */
+ session->nWpaRsnReqIeLength = 0;
+ if(session->pWpaRsnReqIE)
+ {
+ vos_mem_free(session->pWpaRsnReqIE);
+ session->pWpaRsnReqIE = NULL;
+ }
+#ifdef FEATURE_WLAN_WAPI
+ session->nWapiReqIeLength = 0;
+ if(session->pWapiReqIE)
+ {
+ vos_mem_free(session->pWapiReqIE);
+ session->pWapiReqIE = NULL;
+ }
+#endif
+ /* length is two bytes */
+ *buf = 0;
+ *(buf + 1) = 0;
+ buf += 2;
+ }
+#ifdef FEATURE_WLAN_ESE
+ if(eWNI_SME_JOIN_REQ == message_type)
+ {
+ /*
+ * Never include the cckmIE in an Join Request
+ * length is two bytes
+ */
+ *buf = 0;
+ *(buf + 1) = 0;
+ buf += 2;
+ }
+ else if(eWNI_SME_REASSOC_REQ == message_type)
+ {
+ /* cckmIE */
+ if( csrIsProfileESE(profile))
+ {
+ /* Insert the CCKM IE into the join request */
+#ifdef FEATURE_WLAN_ESE_UPLOAD
+ ie_len = session->suppCckmIeInfo.cckmIeLen;
+ vos_mem_copy((void *) (wpa_rsn_ie),
+ session->suppCckmIeInfo.cckmIe, ie_len);
+#else
+ ie_len = csrConstructEseCckmIe(mac,
+ session,
+ profile,
+ bss_description,
+ session->pWpaRsnReqIE,
+ session->nWpaRsnReqIeLength,
+ (void *)(wpa_rsn_ie));
+#endif
+ }
+ else
+ {
+ ie_len = 0;
+ }
+ /*
+ * If present, copy the IE into the eWNI_SME_REASSOC_REQ
+ * message buffer
+ */
+ if(ie_len)
+ {
+ /* Copy the CCKM IE over from the temp buffer (wpaRsnIE) */
+ w_tmp = pal_cpu_to_be16(ie_len);
+ vos_mem_copy(buf, &w_tmp, sizeof(tANI_U16));
+ buf += sizeof(tANI_U16);
+ vos_mem_copy(buf, wpa_rsn_ie, ie_len);
+ buf += ie_len;
+ }
+ else
+ {
+ /* Indicate you have no CCKM IE length is two bytes */
+ *buf = 0;
+ *(buf + 1) = 0;
+ buf += 2;
+ }
+ }
+#endif
+ /* addIEScan */
+ if (profile->nAddIEScanLength)
+ {
+ ie_len = profile->nAddIEScanLength;
+ memset(session->addIEScan, 0 , session->nAddIEScanLength);
+ session->nAddIEScanLength = ie_len;
+ vos_mem_copy(session->addIEScan, profile->addIEScan, ie_len);
+ w_tmp = pal_cpu_to_be16(ie_len);
+ vos_mem_copy(buf, &w_tmp, sizeof(tANI_U16));
+ buf += sizeof(tANI_U16);
+ vos_mem_copy(buf, profile->addIEScan, ie_len);
+ buf += ie_len;
+ }
+ else
+ {
+ memset(session->addIEScan, 0, session->nAddIEScanLength);
+ session->nAddIEScanLength = 0;
+ *buf = 0;
+ *(buf + 1) = 0;
+ buf += 2;
+ }
+ /* addIEAssoc */
+ if(profile->nAddIEAssocLength && profile->pAddIEAssoc)
+ {
+ ie_len = profile->nAddIEAssocLength;
+ if(ie_len > session->nAddIEAssocLength)
+ {
+ if(session->pAddIEAssoc && session->nAddIEAssocLength)
+ {
+ vos_mem_free(session->pAddIEAssoc);
+ }
+ session->pAddIEAssoc = vos_mem_malloc(ie_len);
+ if (NULL == session->pAddIEAssoc)
+ status = eHAL_STATUS_FAILURE;
+ else
+ status = eHAL_STATUS_SUCCESS;
+ if(!HAL_STATUS_SUCCESS(status)) break;
+ }
+ session->nAddIEAssocLength = ie_len;
+ vos_mem_copy(session->pAddIEAssoc, profile->pAddIEAssoc, ie_len);
+ w_tmp = pal_cpu_to_be16(ie_len);
+ vos_mem_copy(buf, &w_tmp, sizeof(tANI_U16));
+ buf += sizeof(tANI_U16);
+ vos_mem_copy(buf, profile->pAddIEAssoc, ie_len);
+ buf += ie_len;
+ }
+ else
+ {
+ session->nAddIEAssocLength = 0;
+ if(session->pAddIEAssoc)
+ {
+ vos_mem_free(session->pAddIEAssoc);
+ session->pAddIEAssoc = NULL;
+ }
+ *buf = 0;
+ *(buf + 1) = 0;
+ buf += 2;
+ }
+
+ if(eWNI_SME_REASSOC_REQ == message_type )
+ {
+ /*Unmask any AC in reassoc that is ACM-set */
+ uapsd_mask = (v_U8_t)profile->uapsd_mask;
+ if( uapsd_mask && (NULL != bss_description))
+ {
+ if( CSR_IS_QOS_BSS(ies) && CSR_IS_UAPSD_BSS(ies) )
+ {
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+ acm_mask = sme_QosGetACMMask(mac, bss_description, ies);
+#endif
+ }
+ else
+ {
+ uapsd_mask = 0;
+ }
+ }
+ }
+
+ dw_tmp = pal_cpu_to_be32(csrTranslateEncryptTypeToEdType(
+ profile->negotiatedUCEncryptionType));
+ vos_mem_copy(buf, &dw_tmp, sizeof(tANI_U32));
+ buf += sizeof(tANI_U32);
+
+ dw_tmp = pal_cpu_to_be32(csrTranslateEncryptTypeToEdType(
+ profile->negotiatedMCEncryptionType));
+ vos_mem_copy(buf, &dw_tmp, sizeof(tANI_U32));
+ buf += sizeof(tANI_U32);
+#ifdef WLAN_FEATURE_11W
+ /* MgmtEncryption */
+ if (profile->MFPEnabled)
+ {
+ dw_tmp = pal_cpu_to_be32(eSIR_ED_AES_128_CMAC);
+ }
+ else
+ {
+ dw_tmp = pal_cpu_to_be32(eSIR_ED_NONE);
+ }
+ vos_mem_copy(buf, &dw_tmp, sizeof(tANI_U32));
+ buf += sizeof(tANI_U32);
+#endif
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ profile->MDID.mdiePresent = bss_description->mdiePresent;
+ if (csrIsProfile11r(profile)
+#ifdef FEATURE_WLAN_ESE
+ && !((profile->negotiatedAuthType == eCSR_AUTH_TYPE_OPEN_SYSTEM) &&
+ (ies->ESEVersion.present) &&
+ (mac->roam.configParam.isEseIniFeatureEnabled))
+#endif
+ )
+ {
+ /* is11Rconnection */
+ dw_tmp = pal_cpu_to_be32(TRUE);
+ vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool)) ;
+ buf += sizeof(tAniBool);
+ }
+ else
+ {
+ /* is11Rconnection */
+ dw_tmp = pal_cpu_to_be32(FALSE);
+ vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+ buf += sizeof(tAniBool);
+ }
+#endif
+#ifdef FEATURE_WLAN_ESE
+
+ /* isESEFeatureIniEnabled */
+ if (TRUE == mac->roam.configParam.isEseIniFeatureEnabled)
+ {
+ dw_tmp = pal_cpu_to_be32(TRUE);
+ vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+ buf += sizeof(tAniBool);
+ }
+ else
+ {
+ dw_tmp = pal_cpu_to_be32(FALSE);
+ vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+ buf += sizeof(tAniBool);
+ }
+
+ /* A profile can not be both ESE and 11R. But an 802.11R AP
+ * may be advertising support for ESE as well. So if we are
+ * associating Open or explicitly ESE then we will get ESE.
+ * If we are associating explictly 11R only then we will get
+ * 11R.
+ */
+ if ((csrIsProfileESE(profile) ||
+ ((ies->ESEVersion.present)
+ && ((profile->negotiatedAuthType == eCSR_AUTH_TYPE_OPEN_SYSTEM)
+ || (profile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA)
+ || (profile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA_PSK)
+ || (profile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN)
+#ifdef WLAN_FEATURE_11W
+ || (profile->negotiatedAuthType ==
+ eCSR_AUTH_TYPE_RSN_PSK_SHA256)
+ || (profile->negotiatedAuthType ==
+ eCSR_AUTH_TYPE_RSN_8021X_SHA256)
+#endif
+ || (profile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN_PSK))))
+ && (mac->roam.configParam.isEseIniFeatureEnabled))
+ {
+ /* isESEconnection */
+ dw_tmp = pal_cpu_to_be32(TRUE);
+ vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+ buf += sizeof(tAniBool);
+ }
+ else
+ {
+ /* isESEconnection */
+ dw_tmp = pal_cpu_to_be32(FALSE);
+ vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+ buf += sizeof(tAniBool);
+ }
+
+ if (eWNI_SME_JOIN_REQ == message_type)
+ {
+ tESETspecInfo eseTspec;
+ /*
+ * ESE-Tspec IEs in the ASSOC request is presently not supported
+ * so nullify the TSPEC parameters
+ */
+ vos_mem_set(&eseTspec, sizeof(tESETspecInfo), 0);
+ vos_mem_copy(buf, &eseTspec, sizeof(tESETspecInfo));
+ buf += sizeof(tESETspecInfo);
+ }
+ else if (eWNI_SME_REASSOC_REQ == message_type)
+ {
+ if ((csrIsProfileESE(profile) ||
+ ((ies->ESEVersion.present)
+ && ((profile->negotiatedAuthType == eCSR_AUTH_TYPE_OPEN_SYSTEM)
+ || (profile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA)
+ || (profile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA_PSK)
+ || (profile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN)
+#ifdef WLAN_FEATURE_11W
+ || (profile->negotiatedAuthType ==
+ eCSR_AUTH_TYPE_RSN_PSK_SHA256)
+ || (profile->negotiatedAuthType ==
+ eCSR_AUTH_TYPE_RSN_8021X_SHA256)
+#endif
+ || (profile->negotiatedAuthType ==
+ eCSR_AUTH_TYPE_RSN_PSK))))
+ && (mac->roam.configParam.isEseIniFeatureEnabled))
+ {
+ tESETspecInfo eseTspec;
+ /* ESE Tspec information */
+ vos_mem_set(&eseTspec, sizeof(tESETspecInfo), 0);
+ eseTspec.numTspecs = sme_QosESERetrieveTspecInfo(mac, session_id,
+ (tTspecInfo *) &eseTspec.tspec[0]);
+ *buf = eseTspec.numTspecs;
+ buf += sizeof(tANI_U8);
+ // Copy the TSPEC information only if present
+ if (eseTspec.numTspecs) {
+ vos_mem_copy(buf, (void*)&eseTspec.tspec[0],
+ (eseTspec.numTspecs*sizeof(tTspecInfo)));
+ }
+ buf += sizeof(eseTspec.tspec);
+ }
+ else
+ {
+ tESETspecInfo eseTspec;
+ /*
+ * ESE-Tspec IEs in the ASSOC request is presently
+ * not supported so nullify the TSPEC parameters
+ */
+ vos_mem_set(&eseTspec, sizeof(tESETspecInfo), 0);
+ vos_mem_copy(buf, &eseTspec, sizeof(tESETspecInfo));
+ buf += sizeof(tESETspecInfo);
+ }
+ }
+#endif
+#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
+ /* Fill in isFastTransitionEnabled */
+ if (mac->roam.configParam.isFastTransitionEnabled
+#ifdef FEATURE_WLAN_LFR
+ || csrRoamIsFastRoamEnabled(mac, session_id)
+#endif
+ )
+ {
+ dw_tmp = pal_cpu_to_be32(TRUE);
+ vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+ buf += sizeof(tAniBool);
+ }
+ else
+ {
+ dw_tmp = pal_cpu_to_be32(FALSE);
+ vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+ buf += sizeof(tAniBool);
+ }
+#endif
+#ifdef FEATURE_WLAN_LFR
+ if(csrRoamIsFastRoamEnabled(mac, session_id))
+ {
+ /* legacy fast roaming enabled */
+ dw_tmp = pal_cpu_to_be32(TRUE);
+ vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+ buf += sizeof(tAniBool);
+ }
+ else
+ {
+ dw_tmp = pal_cpu_to_be32(FALSE);
+ vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+ buf += sizeof(tAniBool);
+ }
+#endif
+
+ /* txLdpcIniFeatureEnabled */
+ *buf = (tANI_U8)mac->roam.configParam.txLdpcEnable;
+ buf++;
+
+ if ((csrIs11hSupported(mac)) &&
+ (CSR_IS_CHANNEL_5GHZ(bss_description->channelId)) &&
+ (ies->Country.present) &&\
+ (!mac->roam.configParam.fSupplicantCountryCodeHasPriority))
+ {
+ csrSaveToChannelPower2G_5G(mac,
+ ies->Country.num_triplets * sizeof(tSirMacChanInfo),
+ (tSirMacChanInfo *)(&ies->Country.triplets[0]));
+ csrApplyPower2Current(mac);
+ }
+
+#ifdef WLAN_FEATURE_11AC
+ /* txBFIniFeatureEnabled */
+ *buf = (tANI_U8)mac->roam.configParam.txBFEnable;
+ buf++;
+
+ /* txBFCsnValue */
+ if (IS_BSS_VHT_CAPABLE(ies->VHTCaps))
+ {
+ tx_bf_csn_value = (tANI_U8)mac->roam.configParam.txBFCsnValue;
+ if (ies->VHTCaps.numSoundingDim)
+ tx_bf_csn_value = CSR_ROAM_MIN
+ (tx_bf_csn_value, ies->VHTCaps.numSoundingDim);
+ }
+ *buf = tx_bf_csn_value;
+ buf++;
+
+ /* Only enable MuBf if no other MuBF session exist
+ * and FW and HOST is MuBF capable.
+ */
+ if (IS_MUMIMO_BFORMEE_CAPABLE && (FALSE == mac->isMuBfsessionexist))
+ {
+ *buf = (tANI_U8)mac->roam.configParam.txMuBformee;
+ buf++;
+ }
+ else
+ {
+ *buf = 0;
+ buf++;
+ }
+#endif
+ *buf = (tANI_U8)mac->roam.configParam.isAmsduSupportInAMPDU;
+ buf++;
+
+ /* WME */
+ if(mac->roam.roamSession[session_id].fWMMConnection)
+ {
+ /* WME enabled */
+ dw_tmp = pal_cpu_to_be32(TRUE);
+ vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+ buf += sizeof(tAniBool);
+ }
+ else
+ {
+ dw_tmp = pal_cpu_to_be32(FALSE);
+ vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+ buf += sizeof(tAniBool);
+ }
+
+ /* QOS */
+ if(mac->roam.roamSession[session_id].fQOSConnection)
+ {
+ /* QOS enabled */
+ dw_tmp = pal_cpu_to_be32(TRUE);
+ vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+ buf += sizeof(tAniBool);
+ }
+ else
+ {
+ dw_tmp = pal_cpu_to_be32(FALSE);
+ vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+ buf += sizeof(tAniBool);
+ }
+ /* BssDesc */
+ csrPrepareJoinReassocReqBuffer(mac, bss_description, buf,
+ (tANI_U8)profile->uapsd_mask);
+ } while( 0 );
+
+ smsLog(mac, LOG1, FL("status %d"), status);
+
+ vos_mem_free(profile);
+ return status;
+}
+#endif
+
//
eHalStatus csrSendMBDisassocReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirMacAddr bssId, tANI_U16 reasonCode )
{
@@ -15410,7 +16229,7 @@ static tANI_U32 csrFindIbssSession( tpAniSirGlobal pMac )
}
return (nRet);
}
-static void csrRoamLinkUp(tpAniSirGlobal pMac, tCsrBssid bssid)
+void csrRoamLinkUp(tpAniSirGlobal pMac, tCsrBssid bssid)
{
VOS_STATUS status = VOS_STATUS_SUCCESS;
@@ -17268,6 +18087,8 @@ eHalStatus csrRoamOffloadScan(tpAniSirGlobal pMac, tANI_U8 command, tANI_U8 reas
}
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,"HomeAwayTime:%d",pRequestBuf->HomeAwayTime);
+ pRequestBuf->WeakZoneRssiThresholdForRoam =
+ pMac->roam.configParam.neighborRoamConfig.nWeakZoneRssiThresholdForRoam;
/*Prepare a probe request for 2.4GHz band and one for 5GHz band*/
ucDot11Mode = (tANI_U8) csrTranslateToWNICfgDot11Mode(pMac,
csrFindBestPhyMode( pMac, pMac->roam.configParam.phyMode ));
@@ -17818,6 +18639,10 @@ eHalStatus csrIsFullPowerNeeded( tpAniSirGlobal pMac, tSmeCmd *pCommand,
case eCsrCapsChange:
fNeedFullPower = eANI_BOOLEAN_TRUE;
break;
+ case eCsrForcedDisassocSta:
+ case eCsrForcedDeauthSta:
+ fNeedFullPower = eANI_BOOLEAN_FALSE;
+ break;
default:
//Check whether the profile is already connected. If so, no need for full power
//Note: IBSS is ignored for now because we don't support powersave in IBSS
@@ -18120,6 +18945,59 @@ eHalStatus csrRoamUpdateWPARSNIEs( tpAniSirGlobal pMac, tANI_U32 sessionId, tSir
return ( status );
}
+tANI_U32 csrGetdot11Mode(tHalHandle hHal, tANI_U32 sessionId,
+ tpSirBssDescription pBssDescription)
+{
+ tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+ tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+ eCsrCfgDot11Mode uCfgDot11Mode, cfgDot11Mode;
+ eHalStatus status;
+ tDot11fBeaconIEs *ies_local = NULL;
+ tANI_U32 dot11mode = 0;
+
+ smsLog(pMac, LOG1, FL("phyMode %d"), pSession->pCurRoamProfile->phyMode);
+
+ /* Get IE's */
+ status = csrGetParsedBssDescriptionIEs(pMac, pBssDescription, &ies_local);
+ if (!HAL_STATUS_SUCCESS(status)) {
+ smsLog(pMac, LOGE,
+ FL("csrGetParsedBssDescriptionIEs failed"));
+ return 0;
+ }
+ if(ies_local == NULL) {
+ smsLog(pMac, LOGE,
+ FL("ies_local is NULL"));
+ return 0;
+ }
+
+ if(csrIsPhyModeMatch(pMac, pSession->pCurRoamProfile->phyMode,
+ pBssDescription, pSession->pCurRoamProfile, &cfgDot11Mode, ies_local))
+ uCfgDot11Mode = cfgDot11Mode;
+ else
+ {
+ smsLog(pMac, LOGE, "Can not find match phy mode");
+ if(CSR_IS_CHANNEL_5GHZ(pBssDescription->channelId))
+ uCfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
+ else
+ uCfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
+ }
+
+ /* dot11mode */
+ dot11mode = csrTranslateToWNICfgDot11Mode(pMac, uCfgDot11Mode);
+ smsLog(pMac, LOG1,
+ FL("dot11mode %d uCfgDot11Mode %d"), dot11mode, uCfgDot11Mode);
+
+ if (pBssDescription->channelId <= 14 &&
+ FALSE == pMac->roam.configParam.enableVhtFor24GHz &&
+ WNI_CFG_DOT11_MODE_11AC == dot11mode)
+ {
+ /* Need to disable VHT operation in 2.4 GHz band */
+ dot11mode = WNI_CFG_DOT11_MODE_11N;
+ }
+ vos_mem_free(ies_local);
+ return dot11mode;
+}
+
#ifdef WLAN_FEATURE_VOWIFI_11R
//eHalStatus csrRoamIssueFTPreauthReq(tHalHandle hHal, tANI_U32 sessionId, tCsrBssid preAuthBssid, tANI_U8 channelId)
eHalStatus csrRoamIssueFTPreauthReq(tHalHandle hHal, tANI_U32 sessionId, tpSirBssDescription pBssDescription)
@@ -18145,6 +19023,14 @@ eHalStatus csrRoamIssueFTPreauthReq(tHalHandle hHal, tANI_U32 sessionId, tpSirBs
pftPreAuthReq->messageType = pal_cpu_to_be16(eWNI_SME_FT_PRE_AUTH_REQ);
pftPreAuthReq->preAuthchannelNum = pBssDescription->channelId;
+ pftPreAuthReq->dot11mode =
+ csrGetdot11Mode(hHal, sessionId, pBssDescription);
+ if (!pftPreAuthReq->dot11mode)
+ {
+ smsLog(pMac, LOGE, FL("pftPreAuthReq->dot11mode is zero"));
+ vos_mem_free(pftPreAuthReq);
+ return eHAL_STATUS_FAILURE;
+ }
vos_mem_copy((void *)&pftPreAuthReq->currbssId,
(void *)pSession->connectedProfile.bssid, sizeof(tSirMacAddr));
@@ -18270,6 +19156,10 @@ void csrRoamFTPreAuthRspProcessor( tHalHandle hHal, tpSirFTPreAuthRsp pFTPreAuth
tANI_U16 ft_ies_length;
ft_ies_length = pFTPreAuthRsp->ric_ies_length;
+ if (pMac->roam.roamSession[pMac->ft.ftSmeContext.smeSessionId].
+ connectedProfile.MDID.mdiePresent)
+ pMac->ft.ftSmeContext.addMDIE = TRUE;
+
if ( (pMac->ft.ftSmeContext.reassoc_ft_ies) &&
(pMac->ft.ftSmeContext.reassoc_ft_ies_length))
{
@@ -18277,6 +19167,12 @@ void csrRoamFTPreAuthRspProcessor( tHalHandle hHal, tpSirFTPreAuthRsp pFTPreAuth
pMac->ft.ftSmeContext.reassoc_ft_ies_length = 0;
}
+ if (!ft_ies_length)
+ {
+ pMac->ft.ftSmeContext.psavedFTPreAuthRsp = NULL;
+ return;
+ }
+
pMac->ft.ftSmeContext.reassoc_ft_ies = vos_mem_malloc(ft_ies_length);
if ( NULL == pMac->ft.ftSmeContext.reassoc_ft_ies )
{
diff --git a/drivers/staging/prima/CORE/SME/src/csr/csrApiScan.c b/drivers/staging/prima/CORE/SME/src/csr/csrApiScan.c
index 0cf87c38ba0..4a737a10f9c 100644
--- a/drivers/staging/prima/CORE/SME/src/csr/csrApiScan.c
+++ b/drivers/staging/prima/CORE/SME/src/csr/csrApiScan.c
@@ -1728,13 +1728,8 @@ eHalStatus csrScanHandleSearchForSSID(tpAniSirGlobal pMac, tSmeCmd *pCommand)
smsLog(pMac, LOGE, FL("session %d not found"), sessionId);
break;
}
- /* If Disconnect is already issued from HDD no need to issue connect
- * pSession->abortConnection will not be set in case of try
- * disconnect or hdd stop adaptor use connectState for these cases.
- */
- if (pSession->abortConnection ||
- (pMac->roam.roamSession[sessionId].connectState ==
- eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTING))
+ /* If Disconnect is already issued from HDD no need to issue connect */
+ if (pSession->abortConnection)
{
smsLog(pMac, LOGE,
FL("Disconnect in progress, no need to issue connect"));
@@ -9217,6 +9212,25 @@ eHalStatus csrScanSavePreferredNetworkFound(tpAniSirGlobal pMac,
vos_mem_copy((tANI_U8 *) &pBssDescr->bssId, (tANI_U8 *) macHeader->bssId, sizeof(tSirMacAddr));
pBssDescr->nReceivedTime = vos_timer_get_system_time();
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ // MobilityDomain
+ pBssDescr->mdie[0] = 0;
+ pBssDescr->mdie[1] = 0;
+ pBssDescr->mdie[2] = 0;
+ pBssDescr->mdiePresent = FALSE;
+ // If mdie is present in the probe resp we fill it in the bss description
+ if(pParsedFrame->mdiePresent)
+ {
+ pBssDescr->mdiePresent = TRUE;
+ pBssDescr->mdie[0] = pParsedFrame->mdie[0];
+ pBssDescr->mdie[1] = pParsedFrame->mdie[1];
+ pBssDescr->mdie[2] = pParsedFrame->mdie[2];
+ }
+ smsLog(pMac, LOG1, FL("mdie=%02x%02x%02x"),
+ (unsigned int)pBssDescr->mdie[0], (unsigned int)pBssDescr->mdie[1],
+ (unsigned int)pBssDescr->mdie[2]);
+#endif
+
smsLog( pMac, LOG1, FL("Bssid= "MAC_ADDRESS_STR
" chan= %d, rssi = %d "),
MAC_ADDR_ARRAY(pBssDescr->bssId),
diff --git a/drivers/staging/prima/CORE/SME/src/csr/csrCmdProcess.c b/drivers/staging/prima/CORE/SME/src/csr/csrCmdProcess.c
index e9c47c04be4..c773cc9a128 100644
--- a/drivers/staging/prima/CORE/SME/src/csr/csrCmdProcess.c
+++ b/drivers/staging/prima/CORE/SME/src/csr/csrCmdProcess.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -96,7 +96,9 @@ eHalStatus csrMsgProcessor( tpAniSirGlobal pMac, void *pMsgBuf )
* workable due to failure or finding the condition meets both SAP and infra/IBSS requirement.
*/
if( (eWNI_SME_SETCONTEXT_RSP == pSmeRsp->messageType) ||
- (eWNI_SME_REMOVEKEY_RSP == pSmeRsp->messageType) )
+ (eWNI_SME_REMOVEKEY_RSP == pSmeRsp->messageType) ||
+ (pSmeRsp->messageType == eWNI_SME_FT_PRE_AUTH_RSP) ||
+ (eWNI_SME_GET_STATISTICS_RSP == pSmeRsp->messageType))
{
smsLog(pMac, LOGW, FL(" handling msg 0x%X CSR state is %d"), pSmeRsp->messageType, pMac->roam.curState[pSmeRsp->sessionId]);
csrRoamCheckForLinkStatusChange(pMac, pSmeRsp);
diff --git a/drivers/staging/prima/CORE/SME/src/csr/csrInsideApi.h b/drivers/staging/prima/CORE/SME/src/csr/csrInsideApi.h
index 302b385c68d..2f57205e423 100644
--- a/drivers/staging/prima/CORE/SME/src/csr/csrInsideApi.h
+++ b/drivers/staging/prima/CORE/SME/src/csr/csrInsideApi.h
@@ -257,13 +257,15 @@ struct csr_scan_for_ssid_context
( eCSR_ENCRYPT_TYPE_WEP40 != (encType) ) && \
( eCSR_ENCRYPT_TYPE_WEP104 != (encType) ) )
-#define CSR_IS_DISCONNECT_COMMAND(pCommand) ( ( eSmeCommandRoam == (pCommand)->command ) &&\
- ( ( eCsrForcedDisassoc == (pCommand)->u.roamCmd.roamReason ) ||\
- ( eCsrForcedDeauth == (pCommand)->u.roamCmd.roamReason ) ||\
- ( eCsrSmeIssuedDisassocForHandoff ==\
- (pCommand)->u.roamCmd.roamReason ) ||\
- ( eCsrForcedDisassocMICFailure ==\
- (pCommand)->u.roamCmd.roamReason ) ) )
+#define CSR_IS_DISCONNECT_COMMAND(pCommand) ((eSmeCommandRoam == \
+ (pCommand)->command) &&\
+ ((eCsrForcedDisassoc == (pCommand)->u.roamCmd.roamReason) ||\
+ (eCsrForcedIbssLeave == (pCommand)->u.roamCmd.roamReason) ||\
+ (eCsrForcedDeauth == (pCommand)->u.roamCmd.roamReason) ||\
+ (eCsrSmeIssuedDisassocForHandoff ==\
+ (pCommand)->u.roamCmd.roamReason) ||\
+ (eCsrForcedDisassocMICFailure ==\
+ (pCommand)->u.roamCmd.roamReason)))
eCsrRoamState csrRoamStateChange( tpAniSirGlobal pMac, eCsrRoamState NewRoamState, tANI_U8 sessionId);
eHalStatus csrScanningStateMsgProcessor( tpAniSirGlobal pMac, void *pMsgBuf );
@@ -271,6 +273,10 @@ void csrRoamingStateMsgProcessor( tpAniSirGlobal pMac, void *pMsgBuf );
void csrRoamJoinedStateMsgProcessor( tpAniSirGlobal pMac, void *pMsgBuf );
tANI_BOOLEAN csrScanComplete( tpAniSirGlobal pMac, tSirSmeScanRsp *pScanRsp );
void csrReleaseCommandRoam(tpAniSirGlobal pMac, tSmeCmd *pCommand);
+tpCsrNeighborRoamBSSInfo csrNeighborRoamGetRoamableAPListNextEntry(tpAniSirGlobal pMac,
+ tDblLinkList *pList, tpCsrNeighborRoamBSSInfo pNeighborEntry);
+v_U8_t *csrNeighborRoamStateToString(v_U8_t state);
+void csrReleaseCommandPreauth(tpAniSirGlobal pMac, tSmeCmd *pCommand);
void csrReleaseCommandScan(tpAniSirGlobal pMac, tSmeCmd *pCommand);
void csrReleaseCommandWmStatusChange(tpAniSirGlobal pMac, tSmeCmd *pCommand);
//pIes2 can be NULL
@@ -400,6 +406,10 @@ void csrRoamRemoveDuplicateCommand(tpAniSirGlobal pMac, tANI_U32 sessionId, tSme
eHalStatus csrSendJoinReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirBssDescription *pBssDescription,
tCsrRoamProfile *pProfile, tDot11fBeaconIEs *pIes, tANI_U16 messageType );
eHalStatus csrSendMBDisassocReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirMacAddr bssId, tANI_U16 reasonCode );
+#ifdef WLAN_FEATURE_LFR_MBB
+eHalStatus csr_fill_reassoc_req(tpAniSirGlobal pMac, tANI_U32 sessionId, tSirBssDescription *pBssDescription,
+ tDot11fBeaconIEs *pIes, tSirSmeJoinReq **reassoc_req);
+#endif
eHalStatus csrSendMBDeauthReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirMacAddr bssId, tANI_U16 reasonCode );
eHalStatus csrSendMBDisassocCnfMsg( tpAniSirGlobal pMac, tpSirSmeDisassocInd pDisassocInd );
eHalStatus csrSendMBDeauthCnfMsg( tpAniSirGlobal pMac, tpSirSmeDeauthInd pDeauthInd );
diff --git a/drivers/staging/prima/CORE/SME/src/csr/csrNeighborRoam.c b/drivers/staging/prima/CORE/SME/src/csr/csrNeighborRoam.c
index bce1abd66a3..1467f5919a6 100644
--- a/drivers/staging/prima/CORE/SME/src/csr/csrNeighborRoam.c
+++ b/drivers/staging/prima/CORE/SME/src/csr/csrNeighborRoam.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -72,6 +72,9 @@
#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD)
#include "csrEse.h"
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "csr_roam_mbb.h"
+#endif
#define WLAN_FEATURE_NEIGHBOR_ROAMING_DEBUG 1
#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING_DEBUG
@@ -112,6 +115,9 @@ v_U8_t *csrNeighborRoamStateToString(v_U8_t state)
CASE_RETURN_STRING( eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN );
CASE_RETURN_STRING( eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING );
CASE_RETURN_STRING( eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE );
+#ifdef WLAN_FEATURE_LFR_MBB
+ CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_MBB_PREAUTH_REASSOC);
+#endif
default:
return "eCSR_NEIGHBOR_ROAM_STATE_UNKNOWN";
}
@@ -253,6 +259,36 @@ static eHalStatus csrNeighborRoamTriggerHandoff(tpAniSirGlobal pMac,
tpCsrNeighborRoamControlInfo pNeighborRoamInfo)
{
eHalStatus status = eHAL_STATUS_SUCCESS;
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ smsLog(pMac, LOG1, FL("enable_lfr_mbb %d is mbb supported %d"),
+ pMac->roam.configParam.enable_lfr_mbb,
+ sme_IsFeatureSupportedByFW(MAKE_BEFORE_BREAK));
+
+ if (pMac->roam.configParam.enable_lfr_mbb
+ && sme_IsFeatureSupportedByFW(MAKE_BEFORE_BREAK)
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ && (!pNeighborRoamInfo->is11rAssoc)
+#endif
+#ifdef FEATURE_WLAN_ESE
+ && (!pNeighborRoamInfo->isESEAssoc)
+#endif
+ ) {
+ smsLog(pMac, LOG1,
+ FL("Issuing preauth reassoc"));
+ status = csr_neighbor_roam_issue_preauth_reassoc(pMac);
+ if (eHAL_STATUS_SUCCESS != status)
+ {
+ pMac->ft.ftSmeContext.is_preauth_lfr_mbb = false;
+ smsLog(pMac, LOG1, FL("is_preauth_lfr_mbb %d"),
+ pMac->ft.ftSmeContext.is_preauth_lfr_mbb);
+ }
+ return status;
+ }
+
+
+#endif
+
#ifdef WLAN_FEATURE_VOWIFI_11R
if ((pNeighborRoamInfo->is11rAssoc)
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
@@ -1156,14 +1192,20 @@ eHalStatus csrNeighborRoamPreauthRspHandler(tpAniSirGlobal pMac, tSirRetStatus l
{
tpCsrNeighborRoamBSSInfo pNeighborBssNode = NULL;
tListElem *pEntry;
+ uint32_t retries;
+
+ retries = pMac->sta_auth_retries_for_code17 >
+ CSR_NEIGHBOR_ROAM_MAX_NUM_PREAUTH_RETRIES ?
+ pMac->sta_auth_retries_for_code17 :
+ CSR_NEIGHBOR_ROAM_MAX_NUM_PREAUTH_RETRIES;
smsLog(pMac, LOGE, FL("Preauth failed retry number %d, status = 0x%x"),
pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries, limStatus);
/* Preauth failed. Add the bssId to the preAuth failed list MAC Address. Also remove the AP from roamable AP list */
- if ((pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries >=
- CSR_NEIGHBOR_ROAM_MAX_NUM_PREAUTH_RETRIES) ||
- (eSIR_LIM_MAX_STA_REACHED_ERROR == limStatus))
+ if ((pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries >= retries) ||
+ ((eSIR_LIM_MAX_STA_REACHED_ERROR == limStatus) &&
+ (pMac->sta_auth_retries_for_code17 == 0)))
{
/* We are going to remove the node as it fails for more than MAX tries. Reset this count to 0 */
pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0;
@@ -4426,6 +4468,10 @@ eHalStatus csrNeighborRoamIndicateDisconnect(tpAniSirGlobal pMac, tANI_U8 sessio
*/
CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT);
pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE;
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ pNeighborRoamInfo->uOsRequestedHandoff = 0;
+#endif
+
}
break;
@@ -4453,6 +4499,10 @@ eHalStatus csrNeighborRoamIndicateDisconnect(tpAniSirGlobal pMac, tANI_U8 sessio
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
}
#endif
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ csr_stop_preauth_reassoc_mbb_timer(pMac);
+#endif
break;
case eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN:
@@ -4460,6 +4510,7 @@ eHalStatus csrNeighborRoamIndicateDisconnect(tpAniSirGlobal pMac, tANI_U8 sessio
pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE;
csrNeighborRoamResetCfgListChanScanControlInfo(pMac);
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ pNeighborRoamInfo->uOsRequestedHandoff = 0;
if (!csrRoamIsRoamOffloadScanEnabled(pMac))
{
#endif
@@ -4496,6 +4547,9 @@ eHalStatus csrNeighborRoamIndicateDisconnect(tpAniSirGlobal pMac, tANI_U8 sessio
NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Transitioning to INIT state"));
CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE;
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ pNeighborRoamInfo->uOsRequestedHandoff = 0;
+#endif
break;
}
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
@@ -4571,12 +4625,18 @@ eHalStatus csrNeighborRoamIndicateConnect(tpAniSirGlobal pMac, tANI_U8 sessionId
switch (pNeighborRoamInfo->neighborRoamState)
{
+#ifdef WLAN_FEATURE_LFR_MBB
+ case eCSR_NEIGHBOR_ROAM_STATE_MBB_PREAUTH_REASSOC:
+#endif
case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING:
if (VOS_STATUS_SUCCESS != vosStatus)
{
/* Just transition the state to INIT state. Rest of the clean up happens when we get next connect indication */
CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE;
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ pNeighborRoamInfo->uOsRequestedHandoff = 0;
+#endif
break;
}
/* Fall through if the status is SUCCESS */
@@ -4816,6 +4876,8 @@ eHalStatus csrNeighborRoamInit(tpAniSirGlobal pMac)
pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod = pMac->roam.configParam.neighborRoamConfig.nNeighborResultsRefreshPeriod;
pNeighborRoamInfo->cfgParams.emptyScanRefreshPeriod = pMac->roam.configParam.neighborRoamConfig.nEmptyScanRefreshPeriod;
pNeighborRoamInfo->cfgParams.neighborInitialForcedRoamTo5GhEnable = pMac->roam.configParam.neighborRoamConfig.nNeighborInitialForcedRoamTo5GhEnable;
+ pNeighborRoamInfo->cfgParams.WeakZoneRssiThresholdForRoam =
+ pMac->roam.configParam.neighborRoamConfig.nWeakZoneRssiThresholdForRoam;
pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels =
pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels;
@@ -4943,6 +5005,9 @@ eHalStatus csrNeighborRoamInit(tpAniSirGlobal pMac)
CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE;
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ pNeighborRoamInfo->uOsRequestedHandoff = 0;
+#endif
//Set the Last Sent Cmd as RSO_STOP
pNeighborRoamInfo->lastSentCmd = ROAM_SCAN_OFFLOAD_STOP;
@@ -5268,6 +5333,9 @@ void csrNeighborRoamTranistionPreauthDoneToDisconnected(tpAniSirGlobal pMac)
// Transition to init state
CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE;
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ pNeighborRoamInfo->uOsRequestedHandoff = 0;
+#endif
}
/* ---------------------------------------------------------------------------
@@ -5300,7 +5368,14 @@ tANI_BOOLEAN csrNeighborMiddleOfRoaming (tHalHandle hHal)
(eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING == pMac->roam.neighborRoamInfo.neighborRoamState) ||
(eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE == pMac->roam.neighborRoamInfo.neighborRoamState) ||
(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pMac->roam.neighborRoamInfo.neighborRoamState) ||
- (eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN == pMac->roam.neighborRoamInfo.neighborRoamState);
+ (eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN == pMac->roam.neighborRoamInfo.neighborRoamState)
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ || (eCSR_NEIGHBOR_ROAM_STATE_MBB_PREAUTH_REASSOC ==
+ pMac->roam.neighborRoamInfo.neighborRoamState);
+#else
+ ;
+#endif
return (val);
}
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
diff --git a/drivers/staging/prima/CORE/SME/src/csr/csr_roam_mbb.c b/drivers/staging/prima/CORE/SME/src/csr/csr_roam_mbb.c
new file mode 100644
index 00000000000..f70172217ae
--- /dev/null
+++ b/drivers/staging/prima/CORE/SME/src/csr/csr_roam_mbb.c
@@ -0,0 +1,890 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "aniGlobal.h"
+#include "smeInside.h"
+#include "csrInsideApi.h"
+#include "smsDebug.h"
+#include "macTrace.h"
+#include "csrNeighborRoam.h"
+#include "csr_roam_mbb.h"
+#include "csrInternal.h"
+#include "wlan_qct_wda.h"
+
+eHalStatus csr_register_roaming_mbb_callback(tpAniSirGlobal mac);
+
+#define PREAUTH_REASSOC_MBB_TIMER_VALUE 60
+
+#define CSR_NEIGHBOR_ROAM_STATE_TRANSITION(newState)\
+{\
+ mac->roam.neighborRoamInfo.prevNeighborRoamState = mac->roam.neighborRoamInfo.neighborRoamState;\
+ mac->roam.neighborRoamInfo.neighborRoamState = newState;\
+ VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, \
+ FL("Neighbor Roam Transition from state %s ==> %s"), \
+ csrNeighborRoamStateToString (mac->roam.neighborRoamInfo.prevNeighborRoamState), \
+ csrNeighborRoamStateToString (newState));\
+}
+
+/**
+ * csr_roam_issue_preauth_reassoc_req() -Prepares preauth request
+ * @hal: HAL context
+ * @session_id: session id
+ * @bss_description: BSS description
+ *
+ * This function prepares preauth request and sends request to PE
+ *
+ * Return: eHAL_STATUS_SUCCESS on success,
+ * : eHAL_STATUS_RESOURCES when resource allocation is failure
+ * : eHAL_STATUS_FAILURE otherwise
+ */
+eHalStatus csr_roam_issue_preauth_reassoc_req(tHalHandle hal,
+ tANI_U32 session_id, tpSirBssDescription bss_description)
+{
+ tpAniSirGlobal mac = PMAC_STRUCT(hal);
+ tpSirFTPreAuthReq pre_auth_req;
+ tANI_U16 auth_req_len = 0;
+ tCsrRoamSession *session = CSR_GET_SESSION(mac, session_id);
+ tpCsrNeighborRoamControlInfo neighbor_roam_info =
+ &mac->roam.neighborRoamInfo;
+ eHalStatus status;
+
+ auth_req_len = sizeof(tSirFTPreAuthReq);
+ pre_auth_req = (tpSirFTPreAuthReq)vos_mem_malloc(auth_req_len);
+ if (NULL == pre_auth_req) {
+ smsLog(mac, LOGE,
+ FL("Memory allocation for Preauth request failed"));
+ return eHAL_STATUS_RESOURCES;
+ }
+
+ /*
+ * If neighborRoamState is eCSR_NEIGHBOR_ROAM_STATE_INIT
+ * by the time this API is invoked, disconnect would have happened.
+ * So, need to proceed further.
+ */
+ if (mac->roam.neighborRoamInfo.neighborRoamState ==
+ eCSR_NEIGHBOR_ROAM_STATE_INIT) {
+ smsLog(mac, LOGE, FL("neighborRoamState %d"),
+ mac->roam.neighborRoamInfo.neighborRoamState);
+ return eHAL_STATUS_FAILURE;
+ }
+
+ /*
+ * Save the SME Session ID here. We need it while processing
+ * the preauth response.
+ */
+ mac->ft.ftSmeContext.smeSessionId = session_id;
+ vos_mem_zero(pre_auth_req, auth_req_len);
+
+ pre_auth_req->pbssDescription = (tpSirBssDescription)vos_mem_malloc(
+ sizeof(bss_description->length) + bss_description->length);
+ if (NULL == pre_auth_req->pbssDescription) {
+ smsLog(mac, LOGE,
+ FL("Unable to allocate memory for preauth bss description"));
+ return eHAL_STATUS_RESOURCES;
+ }
+
+ pre_auth_req->messageType =
+ pal_cpu_to_be16(eWNI_SME_MBB_PRE_AUTH_REASSOC_REQ);
+
+ pre_auth_req->preAuthchannelNum = bss_description->channelId;
+
+ vos_mem_copy((void *)&pre_auth_req->currbssId,
+ (void *)session->connectedProfile.bssid, sizeof(tSirMacAddr));
+ vos_mem_copy((void *)&pre_auth_req->preAuthbssId,
+ (void *)bss_description->bssId, sizeof(tSirMacAddr));
+
+ vos_mem_copy(pre_auth_req->pbssDescription, bss_description,
+ sizeof(bss_description->length) + bss_description->length);
+ pre_auth_req->length = pal_cpu_to_be16(auth_req_len);
+
+ /* Register mbb callback */
+ smsLog(mac, LOG1, FL("Registering mbb callback"));
+ csr_register_roaming_mbb_callback(mac);
+
+ csrReleaseProfile(mac, &neighbor_roam_info->csrNeighborRoamProfile);
+
+ /* Copy current profile to be used in csr_update_roamed_info_mbb */
+ status = csrRoamCopyProfile(mac,
+ &neighbor_roam_info->csrNeighborRoamProfile,
+ session->pCurRoamProfile);
+ if(!HAL_STATUS_SUCCESS(status)) {
+ smsLog(mac, LOGE, FL("Profile copy failed"));
+ return status;
+ }
+
+ return palSendMBMessage(mac->hHdd, pre_auth_req);
+}
+
+/**
+ * csr_neighbor_roam_issue_preauth_reassoc() -issues preauth_reassoc request
+ * @mac: MAC context
+ *
+ * This function issues preauth_reassoc request to PE with the 1st AP
+ * entry in the roamable AP list
+ *
+ * Return: eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE otherwise
+ */
+eHalStatus csr_neighbor_roam_issue_preauth_reassoc(tpAniSirGlobal mac)
+{
+ tpCsrNeighborRoamControlInfo neighbor_roam_info =
+ &mac->roam.neighborRoamInfo;
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ tpCsrNeighborRoamBSSInfo neighbor_bss_node;
+ tCsrRoamInfo roam_info;
+
+ VOS_ASSERT(neighbor_roam_info->FTRoamInfo.preauthRspPending ==
+ eANI_BOOLEAN_FALSE);
+
+ neighbor_bss_node = csrNeighborRoamGetRoamableAPListNextEntry(mac,
+ &neighbor_roam_info->roamableAPList, NULL);
+
+ if (neighbor_bss_node == NULL)
+ {
+ smsLog(mac, LOGE, FL("Roamable AP list is empty"));
+ csrRoamOffloadScan(mac, ROAM_SCAN_OFFLOAD_RESTART,
+ REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW);
+ return eHAL_STATUS_FAILURE;
+ }
+ else
+ {
+ /*
+ * Set is_preauth_lfr_mbb which will be checked in
+ * different API's.
+ */
+ mac->ft.ftSmeContext.is_preauth_lfr_mbb = true;
+ smsLog(mac, LOG1, FL("is_preauth_lfr_mbb %d"),
+ mac->ft.ftSmeContext.is_preauth_lfr_mbb);
+
+ status = csrRoamEnqueuePreauth(mac,
+ neighbor_roam_info->csrSessionId,
+ neighbor_bss_node->pBssDescription,
+ ecsr_mbb_perform_preauth_reassoc,
+ eANI_BOOLEAN_TRUE);
+
+ smsLog(mac, LOG1, FL("Before Pre-Auth: BSSID "MAC_ADDRESS_STR", Ch:%d"),
+ MAC_ADDR_ARRAY(neighbor_bss_node->pBssDescription->bssId),
+ neighbor_bss_node->pBssDescription->channelId);
+
+ if (eHAL_STATUS_SUCCESS != status)
+ {
+ smsLog(mac, LOGE,
+ FL("Send Preauth request to PE failed with status %d"),
+ status);
+ return status;
+ }
+ }
+
+ neighbor_roam_info->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_TRUE;
+
+ CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_MBB_PREAUTH_REASSOC)
+
+ if (csrRoamIsFastRoamEnabled(mac, CSR_SESSION_ID_INVALID))
+ {
+ smsLog(mac, LOG1, FL("Invoking eCSR_ROAM_PMK_NOTIFY"));
+ vos_mem_copy((void *)&roam_info.bssid,
+ (void *)neighbor_bss_node->pBssDescription->bssId,
+ sizeof(tCsrBssid));
+ csrRoamCallCallback(mac, neighbor_roam_info->csrSessionId, &roam_info,
+ 0, eCSR_ROAM_PMK_NOTIFY, 0);
+ }
+ return status;
+}
+
+/**
+ * csr_stop_preauth_reassoc_mbb_timer() -stops preauth_reassoc timer
+ * @mac: MAC context
+ *
+ * This function stops preauth_reassoc timer
+ *
+ */
+void csr_stop_preauth_reassoc_mbb_timer(tpAniSirGlobal mac)
+{
+ VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
+
+ if (mac->roam.neighborRoamInfo.is_pre_auth_reassoc_mbb_timer_started) {
+ vos_status =
+ vos_timer_stop(&mac->ft.ftSmeContext.pre_auth_reassoc_mbb_timer);
+ mac->roam.neighborRoamInfo.is_pre_auth_reassoc_mbb_timer_started =
+ false;
+ }
+}
+
+
+/**
+ * csr_preauth_reassoc_mbb_timer_callback() -preauth_reassoc timer callback
+ * @mac: MAC context
+ *
+ * This function issues preauth_reassoc with another roamable entry
+ *
+ */
+void csr_preauth_reassoc_mbb_timer_callback(void *context)
+{
+ tpAniSirGlobal mac = (tpAniSirGlobal)context;
+
+ mac->roam.neighborRoamInfo.is_pre_auth_reassoc_mbb_timer_started = 0;
+
+ smsLog(mac, LOG1, FL("is_pre_auth_reassoc_mbb_timer_started %d"),
+ mac->roam.neighborRoamInfo.is_pre_auth_reassoc_mbb_timer_started);
+
+ csr_neighbor_roam_issue_preauth_reassoc(mac);
+}
+
+
+/**
+ * csr_roam_dequeue_preauth_reassoc() -Dequeues
+ * ecsr_mbb_perform_preauth_reassoc
+ * @mac: MAC context
+ *
+ * This function dequeues ecsr_mbb_perform_preauth_reassoc
+ *
+ */
+eHalStatus csr_roam_dequeue_preauth_reassoc(tpAniSirGlobal mac)
+{
+ tListElem *entry;
+ tSmeCmd *command;
+ entry = csrLLPeekHead(&mac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
+ if (entry) {
+ command = GET_BASE_ADDR(entry, tSmeCmd, Link);
+ if ((eSmeCommandRoam == command->command) &&
+ (ecsr_mbb_perform_preauth_reassoc ==
+ command->u.roamCmd.roamReason)) {
+ smsLog(mac, LOG1, FL("DQ-Command = %d, Reason = %d"),
+ command->command, command->u.roamCmd.roamReason);
+ if (csrLLRemoveEntry( &mac->sme.smeCmdActiveList,
+ entry, LL_ACCESS_LOCK)) {
+ csrReleaseCommandPreauth( mac, command );
+ }
+ } else {
+ smsLog(mac, LOGE, FL("Command = %d, Reason = %d "),
+ command->command, command->u.roamCmd.roamReason);
+ }
+ }
+ else {
+ smsLog(mac, LOGE,
+ FL("pEntry NULL for eWNI_SME_MBB_PRE_AUTH_REASSOC_RSP"));
+ }
+ smeProcessPendingQueue( mac );
+ return eHAL_STATUS_SUCCESS;
+}
+
+/**
+ * csr_neighbor_roam_preauth_reassoc_rsp_handler() -handles preauth
+ * reassoc response
+ * @mac: MAC context
+ * @lim_status: status of preauth reassoc response from lim
+ * @bss_description: bss description pointer
+ *
+ * This function handles preauth_reassoc response from PE. When
+ * preauth_reassoc response failure is received, preauth reassoc
+ * with new candidate will be attempted. In success case, candidate will be
+ * removed from roamable entry.
+ *
+ */
+eHalStatus
+csr_neighbor_roam_preauth_reassoc_rsp_handler(tpAniSirGlobal mac,
+ tSirRetStatus lim_status, tSirBssDescription **bss_description)
+{
+ tpCsrNeighborRoamControlInfo neighbor_roam_info =
+ &mac->roam.neighborRoamInfo;
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ eHalStatus preauth_processed = eHAL_STATUS_SUCCESS;
+ tpCsrNeighborRoamBSSInfo preauth_rsp_node = NULL;
+
+ if (eANI_BOOLEAN_FALSE ==
+ neighbor_roam_info->FTRoamInfo.preauthRspPending) {
+ /*
+ * This can happen when we disconnect immediately after sending
+ * a pre-auth request. During processing of the disconnect command,
+ * we would have reset preauthRspPending and transitioned to INIT state.
+ */
+ smsLog(mac, LOGE,
+ FL("Unexpected pre-auth response in state %d"),
+ neighbor_roam_info->neighborRoamState);
+ preauth_processed = eHAL_STATUS_FAILURE;
+ goto DEQ_PREAUTH;
+ }
+
+ if ((neighbor_roam_info->neighborRoamState !=
+ eCSR_NEIGHBOR_ROAM_STATE_MBB_PREAUTH_REASSOC)) {
+ smsLog(mac, LOGE,
+ FL("Preauth response received in state %s"),
+ macTraceGetNeighbourRoamState(
+ neighbor_roam_info->neighborRoamState));
+ preauth_processed = eHAL_STATUS_FAILURE;
+ goto DEQ_PREAUTH;
+ }
+
+ neighbor_roam_info->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_FALSE;
+
+ if (eSIR_SUCCESS == lim_status)
+ preauth_rsp_node = csrNeighborRoamGetRoamableAPListNextEntry(mac,
+ &neighbor_roam_info->roamableAPList, NULL);
+
+ if ((eSIR_SUCCESS == lim_status) && (NULL != preauth_rsp_node)) {
+ smsLog(mac, LOG1, FL("MBB Reassoc completed successfully"));
+
+ smsLog(mac, LOG1, FL("After MBB reassoc BSSID "MAC_ADDRESS_STR" Ch %d"),
+ MAC_ADDR_ARRAY(preauth_rsp_node->pBssDescription->bssId),
+ preauth_rsp_node->pBssDescription->channelId);
+
+ /* Memory will be freed in caller of this */
+ *bss_description = (tpSirBssDescription)vos_mem_malloc(
+ sizeof(preauth_rsp_node->pBssDescription->length) +
+ preauth_rsp_node->pBssDescription->length);
+ if (NULL == *bss_description) {
+ smsLog(mac, LOGE,
+ FL("Unable to allocate memory for preauth bss description"));
+ preauth_processed = eHAL_STATUS_RESOURCES;
+ goto DEQ_PREAUTH;
+ }
+
+ vos_mem_copy(*bss_description, preauth_rsp_node->pBssDescription,
+ sizeof(preauth_rsp_node->pBssDescription->length) +
+ preauth_rsp_node->pBssDescription->length);
+
+ /*
+ * MBB Reassoc competer successfully. Insert the preauthenticated
+ * node to tail of preAuthDoneList
+ */
+ csrNeighborRoamRemoveRoamableAPListEntry(mac,
+ &neighbor_roam_info->roamableAPList, preauth_rsp_node);
+ csrLLInsertTail(&neighbor_roam_info->FTRoamInfo.preAuthDoneList,
+ &preauth_rsp_node->List, LL_ACCESS_LOCK);
+ return eHAL_STATUS_SUCCESS;
+ } else {
+ tpCsrNeighborRoamBSSInfo neighbor_bss_node = NULL;
+ tListElem *entry;
+
+ /*
+ * Pre-auth failed. Add the bssId to the preAuth failed list MAC Address.
+ * Also remove the AP from roamable AP list. The one in the head of the
+ * list should be one with which we issued pre-auth and failed.
+ */
+ entry = csrLLRemoveHead(&neighbor_roam_info->roamableAPList,
+ LL_ACCESS_LOCK);
+ if(entry) {
+ neighbor_bss_node = GET_BASE_ADDR(entry,
+ tCsrNeighborRoamBSSInfo, List);
+ /*
+ * Add the BSSID to pre-auth fail list if it is
+ * not requested by HDD
+ */
+ status = csrNeighborRoamAddBssIdToPreauthFailList(mac,
+ neighbor_bss_node->pBssDescription->bssId);
+
+ smsLog(mac, LOG1,
+ FL("MBB reassoc failed BSSID "MAC_ADDRESS_STR" Ch:%d status %d"),
+ MAC_ADDR_ARRAY(neighbor_bss_node->pBssDescription->bssId),
+ neighbor_bss_node->pBssDescription->channelId, lim_status);
+
+ /* Now we can free this node */
+ csrNeighborRoamFreeNeighborRoamBSSNode(mac, neighbor_bss_node);
+ }
+
+ /*
+ * Move state to Connected. Connected state here signifies connection
+ * with current AP as preauth failed with roamable AP. Still driver has
+ * connection with current AP.
+ */
+ CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED)
+
+ /* Start a timer to issue preauth_reassoc request for the next entry*/
+ status = vos_timer_start(&mac->ft.ftSmeContext.
+ pre_auth_reassoc_mbb_timer, PREAUTH_REASSOC_MBB_TIMER_VALUE);
+ if (eHAL_STATUS_SUCCESS != status) {
+ smsLog(mac, LOGE,
+ FL("pre_auth_reassoc_mbb_timer start failed status %d"),
+ status);
+ preauth_processed = eHAL_STATUS_FAILURE;
+ goto DEQ_PREAUTH;
+ }
+ mac->roam.neighborRoamInfo.is_pre_auth_reassoc_mbb_timer_started = true;
+ smsLog(mac, LOG1, FL("is_pre_auth_reassoc_mbb_timer_started %d"),
+ mac->roam.neighborRoamInfo.is_pre_auth_reassoc_mbb_timer_started);
+ preauth_processed = eHAL_STATUS_SUCCESS;
+ }
+
+DEQ_PREAUTH:
+ csr_roam_dequeue_preauth_reassoc(mac);
+ return preauth_processed;
+}
+
+eHalStatus csr_update_roamed_info_mbb(tHalHandle hal,
+ tpSirBssDescription bss_description, tpSirFTPreAuthRsp pre_auth_rsp)
+{
+ eHalStatus status;
+ tpAniSirGlobal mac = PMAC_STRUCT(hal);
+ tDot11fBeaconIEs *ies_local = NULL;
+ tCsrRoamSession *session = NULL;
+ tCsrRoamProfile *profile;
+ tSirMacAddr broadcast_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ tANI_U32 key_timeout_interval;
+ tCsrRoamInfo roam_info;
+ sme_QosAssocInfo assoc_info;
+ tANI_U32 len;
+ tANI_U8 sme_session_id = pre_auth_rsp->smeSessionId;
+ tANI_U8 acm_mask = 0;
+
+ /* Get profile */
+ session = CSR_GET_SESSION(mac, sme_session_id);
+
+ profile = vos_mem_malloc(sizeof(*profile));
+ if (NULL == profile) {
+ smsLog(mac, LOGE, FL("Memory allocation failure for profile"));
+ return eHAL_STATUS_FAILURE;
+ }
+
+ /*
+ * session->pCurRoamProfile is copied into csrNeighborRoamProfile
+ * in csr_roam_issue_preauth_reassoc_req as there is a chance of
+ * session->pCurRoamProfile getting freed when disconnect is issued
+ * from upper layer.
+ */
+ status = csrRoamCopyProfile(mac, profile,
+ &mac->roam.neighborRoamInfo.csrNeighborRoamProfile);
+ if(!HAL_STATUS_SUCCESS(status)) {
+ smsLog(mac, LOGE, FL("Profile copy failed"));
+ vos_mem_free(profile);
+ return status;
+ }
+
+ profile->negotiatedAuthType =
+ mac->roam.roamSession[sme_session_id].connectedProfile.AuthType;
+ profile->negotiatedUCEncryptionType =
+ mac->roam.roamSession[sme_session_id].connectedProfile.EncryptionType;
+ profile->mcEncryptionType =
+ mac->roam.roamSession[sme_session_id].connectedProfile.mcEncryptionInfo;
+ profile->negotiatedMCEncryptionType =
+ mac->roam.roamSession[sme_session_id].connectedProfile.mcEncryptionType;
+
+ smsLog(mac, LOG1,
+ FL("AuthType %d UCEType %d Entries %d encryptionType %d MCEType %d"),
+ profile->negotiatedAuthType,
+ profile->negotiatedUCEncryptionType,
+ profile->mcEncryptionType.numEntries,
+ profile->mcEncryptionType.encryptionType[0],
+ profile->negotiatedMCEncryptionType);
+
+ /* Get IE's */
+ status = csrGetParsedBssDescriptionIEs(mac, bss_description, &ies_local);
+ if (!HAL_STATUS_SUCCESS(status)) {
+ smsLog(mac, LOGE,
+ FL("csrGetParsedBssDescriptionIEs failed"));
+ vos_mem_free(profile);
+ return status;
+ }
+ if(ies_local == NULL) {
+ smsLog(mac, LOGE,
+ FL("ies_local is NULL "));
+ vos_mem_free(profile);
+ return eHAL_STATUS_FAILURE;
+ }
+
+ vos_mem_set(&roam_info, sizeof(roam_info), 0);
+
+ csrRoamStopNetwork(mac, sme_session_id, profile,
+ bss_description, ies_local);
+
+ session->connectState = eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED;
+
+ csrRoamSaveConnectedInfomation(mac, sme_session_id, profile,
+ bss_description, ies_local);
+ csrRoamSaveSecurityRspIE(mac, sme_session_id,
+ profile->negotiatedAuthType, bss_description,
+ ies_local);
+
+ csrRoamStateChange(mac, eCSR_ROAMING_STATE_JOINED, sme_session_id);
+
+ /*
+ * If abortConnection is set, it implies that disconnect in progress
+ * from upper layer. So there is no point in proceeding further.
+ * By this point, pConnectBssDesc is updated in
+ * csrRoamSaveConnectedInfomation. This pConnectBssDesc is used
+ * during processing of disconnect in CSR and this has new BSSID info.
+ * By this time, original AP related info was cleaned up in LIM. So,
+ * disconnect queued while roaming in progress will take care of
+ * cleaning up roamed AP related info in LIM.
+ */
+ if (session->abortConnection) {
+ smsLog(mac, LOGE, FL("Disconnect in progress"));
+
+ smsLog(mac, LOGE, FL("MBB reassoc BSSID "MAC_ADDRESS_STR" Ch %d"),
+ MAC_ADDR_ARRAY(bss_description->bssId),
+ bss_description->channelId);
+
+ vos_mem_free(profile);
+ return eHAL_STATUS_FAILURE;
+ }
+
+ if(CSR_IS_ENC_TYPE_STATIC(profile->negotiatedUCEncryptionType) &&
+ !profile->bWPSAssociation) {
+ /*
+ * Issue the set Context request to LIM to establish the
+ * Unicast STA context
+ */
+ if(!HAL_STATUS_SUCCESS(csrRoamIssueSetContextReq(mac,
+ sme_session_id,
+ profile->negotiatedUCEncryptionType,
+ bss_description, &(bss_description->bssId), FALSE, TRUE,
+ eSIR_TX_RX, 0, 0, NULL, 0))) {
+ smsLog(mac, LOGE, FL("Set context for unicast fail"));
+ csrRoamSubstateChange(mac, eCSR_ROAM_SUBSTATE_NONE,
+ sme_session_id);
+ }
+ /*
+ * Issue the set Context request to LIM to establish the
+ * Broadcast STA context
+ */
+ csrRoamIssueSetContextReq(mac, sme_session_id,
+ profile->negotiatedMCEncryptionType,
+ bss_description, &broadcast_mac,
+ FALSE, FALSE, eSIR_TX_RX, 0, 0, NULL, 0);
+ } else if (!session->abortConnection) {
+ /* Need to wait for supplicant authtication */
+ roam_info.fAuthRequired = eANI_BOOLEAN_TRUE;
+ /* Set the subestate to WaitForKey in case authentiation is needed */
+ csrRoamSubstateChange(mac, eCSR_ROAM_SUBSTATE_WAIT_FOR_KEY,
+ sme_session_id);
+
+ if(profile->bWPSAssociation)
+ key_timeout_interval = CSR_WAIT_FOR_WPS_KEY_TIMEOUT_PERIOD;
+ else
+ key_timeout_interval = CSR_WAIT_FOR_KEY_TIMEOUT_PERIOD;
+
+ /* Save sessionId in case of timeout */
+ mac->roam.WaitForKeyTimerInfo.sessionId = sme_session_id;
+ /*
+ * This time should be long enough for the rest of the
+ * process plus setting key
+ */
+ if(!HAL_STATUS_SUCCESS(csrRoamStartWaitForKeyTimer(mac,
+ key_timeout_interval))) {
+ /* Reset our state so nothting is blocked */
+ smsLog(mac, LOGE, FL("Failed to start pre-auth timer"));
+ csrRoamSubstateChange(mac, eCSR_ROAM_SUBSTATE_NONE,
+ sme_session_id);
+ }
+ }
+
+ csrRoamFreeConnectedInfo(mac, &session->connectedInfo);
+
+ assoc_info.pBssDesc = bss_description;
+ assoc_info.pProfile = profile;
+
+ len = pre_auth_rsp->roam_info->nBeaconLength +
+ pre_auth_rsp->roam_info->nAssocReqLength +
+ pre_auth_rsp->roam_info->nAssocRspLength;
+
+ if(len) {
+ session->connectedInfo.pbFrames = vos_mem_malloc(len);
+ if (session->connectedInfo.pbFrames != NULL ) {
+ vos_mem_copy(session->connectedInfo.pbFrames,
+ pre_auth_rsp->roam_info->pbFrames, len);
+ session->connectedInfo.nAssocReqLength =
+ pre_auth_rsp->roam_info->nAssocReqLength;
+ session->connectedInfo.nAssocRspLength =
+ pre_auth_rsp->roam_info->nAssocRspLength;
+ session->connectedInfo.nBeaconLength =
+ pre_auth_rsp->roam_info->nBeaconLength;
+
+ roam_info.nAssocReqLength = pre_auth_rsp->roam_info->nAssocReqLength;
+ roam_info.nAssocRspLength = pre_auth_rsp->roam_info->nAssocRspLength;
+ roam_info.nBeaconLength = pre_auth_rsp->roam_info->nBeaconLength;
+ roam_info.pbFrames = session->connectedInfo.pbFrames;
+ }
+ session->connectedInfo.staId = pre_auth_rsp->roam_info->staId;
+ roam_info.staId = pre_auth_rsp->roam_info->staId;
+ roam_info.ucastSig = pre_auth_rsp->roam_info->ucastSig;
+ roam_info.bcastSig = pre_auth_rsp->roam_info->bcastSig;
+ roam_info.maxRateFlags = pre_auth_rsp->roam_info->maxRateFlags;
+ }
+
+ roam_info.statusCode = eSIR_SME_SUCCESS;
+ roam_info.reasonCode = eSIR_SME_SUCCESS;
+ roam_info.pBssDesc = bss_description;
+
+ vos_mem_copy(&roam_info.bssid, &bss_description->bssId,
+ sizeof(tCsrBssid));
+
+ mac->roam.roamSession[sme_session_id].connectState =
+ eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
+
+ sme_QosCsrEventInd(mac, sme_session_id,
+ SME_QOS_CSR_HANDOFF_ASSOC_REQ, NULL);
+ sme_QosCsrEventInd(mac, sme_session_id, SME_QOS_CSR_REASSOC_REQ, NULL);
+ sme_QosCsrEventInd(mac, sme_session_id, SME_QOS_CSR_HANDOFF_COMPLETE, NULL);
+
+ mac->roam.roamSession[sme_session_id].connectState =
+ eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED;
+ sme_QosCsrEventInd(mac, sme_session_id,
+ SME_QOS_CSR_REASSOC_COMPLETE, &assoc_info);
+
+
+ acm_mask = sme_QosGetACMMask(mac, bss_description, NULL);
+
+ session->connectedProfile.acm_mask = acm_mask;
+ if(session->connectedProfile.modifyProfileFields.uapsd_mask) {
+ smsLog(mac, LOGE, "uapsd_mask (0x%X) set, request UAPSD now",
+ session->connectedProfile.modifyProfileFields.uapsd_mask);
+ pmcStartUapsd(mac, NULL, NULL);
+ }
+ session->connectedProfile.dot11Mode = session->bssParams.uCfgDot11Mode;
+ roam_info.u.pConnectedProfile = &session->connectedProfile;
+
+ if(!IS_FEATURE_SUPPORTED_BY_FW(SLM_SESSIONIZATION) &&
+ (csrIsConcurrentSessionRunning(mac)))
+ mac->roam.configParam.doBMPSWorkaround = 1;
+
+ csr_roam_dequeue_preauth_reassoc(mac);
+
+ csrRoamCallCallback(mac, sme_session_id, &roam_info, 0,
+ eCSR_ROAM_ASSOCIATION_COMPLETION, eCSR_ROAM_RESULT_ASSOCIATED);
+
+ csrResetPMKIDCandidateList(mac, sme_session_id);
+#ifdef FEATURE_WLAN_WAPI
+ csrResetBKIDCandidateList(mac, sme_session_id);
+#endif
+
+ if(!CSR_IS_WAIT_FOR_KEY(mac, sme_session_id)) {
+ smsLog(mac, LOG1, "NO CSR_IS_WAIT_FOR_KEY -> csr_roam_link_up");
+ csrRoamLinkUp(mac, session->connectedProfile.bssid);
+ }
+
+ if (pmcShouldBmpsTimerRun(mac)) {
+ if(eANI_BOOLEAN_TRUE == roam_info.fAuthRequired) {
+ mac->pmc.full_power_till_set_key = true;
+ smsLog(mac, LOG1,
+ FL("full_power_till_set_key is made true"));
+ }
+
+ if (pmcStartTrafficTimer(mac, BMPS_TRAFFIC_TIMER_ALLOW_SECURITY_DHCP)
+ != eHAL_STATUS_SUCCESS)
+ smsLog(mac, LOGE, FL("Cannot start BMPS Retry timer"));
+
+ smsLog(mac, LOG1, FL("BMPS Retry Timer already running or started"));
+ }
+
+ vos_mem_free(pre_auth_rsp->roam_info->pbFrames);
+ vos_mem_free(pre_auth_rsp->roam_info);
+ vos_mem_free(profile);
+ vos_mem_free(ies_local);
+
+ return eHAL_STATUS_SUCCESS;
+}
+
+
+/**
+ * csr_roam_preauth_rsp_mbb_processor() -handles
+ * eWNI_SME_MBB_PRE_AUTH_REASSOC_RSP
+ * @hal: HAL context
+ *
+ * This function invokes preauth reassoc response handler and
+ * updates CSR with new connection information.
+ *
+ */
+void csr_roam_preauth_rsp_mbb_processor(tHalHandle hal,
+ tpSirFTPreAuthRsp pre_auth_rsp)
+{
+ tpAniSirGlobal mac = PMAC_STRUCT(hal);
+ eHalStatus status;
+ tCsrRoamInfo roam_info;
+ tpSirBssDescription bss_description = NULL;
+ tCsrRoamSession *session = NULL;
+
+ mac->ft.ftSmeContext.is_preauth_lfr_mbb = false;
+ smsLog(mac, LOG1, FL("is_preauth_lfr_mbb %d"),
+ mac->ft.ftSmeContext.is_preauth_lfr_mbb);
+
+ /*
+ * When reason is SIR_MBB_DISCONNECTED, cleanup CSR info
+ * of connected AP.
+ */
+ if (pre_auth_rsp->reason == SIR_MBB_DISCONNECTED) {
+ /* Dequeue ecsr_perform_preauth_reassoc */
+ csr_roam_dequeue_preauth_reassoc(mac);
+
+ vos_mem_zero(&roam_info, sizeof(tCsrRoamInfo));
+ csrRoamCallCallback(mac, pre_auth_rsp->smeSessionId, &roam_info, 0,
+ eCSR_ROAM_FT_REASSOC_FAILED, eSIR_SME_SUCCESS);
+
+ csrRoamComplete(mac, eCsrJoinFailure, NULL);
+ }
+
+ status = csr_neighbor_roam_preauth_reassoc_rsp_handler(mac,
+ pre_auth_rsp->status, &bss_description);
+ if (status != eHAL_STATUS_SUCCESS) {
+ smsLog(mac, LOGE,FL("Preauth was not processed: %d SessionID: %d"),
+ status, pre_auth_rsp->smeSessionId);
+ /*
+ * Preauth_reassoc is dequeued already in
+ * csr_neighbor_roam_preauth_reassoc_rsp_handler for error cases.
+ */
+ return;
+ }
+
+ session = CSR_GET_SESSION(mac, pre_auth_rsp->smeSessionId);
+ if (session->abortConnection) {
+ smsLog(mac, LOGE,
+ FL("Disconnect in progress, stop preauth/reassoc timer"));
+ vos_timer_stop(&mac->ft.ftSmeContext.pre_auth_reassoc_mbb_timer);
+ }
+
+ /*
+ * The below function calls/timers should be invoked only
+ * if the pre-auth is successful. Also, Preauth_reassoc is dequeued
+ * already in csr_neighbor_roam_preauth_reassoc_rsp_handler.
+ */
+ if (VOS_STATUS_SUCCESS != (VOS_STATUS)pre_auth_rsp->status)
+ return;
+
+ mac->ft.ftSmeContext.FTState = eFT_AUTH_COMPLETE;
+
+ /* Save the received response */
+ vos_mem_copy((void *)&mac->ft.ftSmeContext.preAuthbssId,
+ (void *)pre_auth_rsp->preAuthbssId, sizeof(tCsrBssid));
+
+
+ /*
+ * bss_description is updated in
+ * csr_neighbor_roam_preauth_reassoc_rsp_handler
+ */
+ if (NULL == bss_description) {
+ smsLog(mac, LOGE,
+ FL("bss description is NULL"));
+ goto DEQ_PREAUTH;
+ }
+
+ /* Update CSR for new connection */
+ status = csr_update_roamed_info_mbb(hal, bss_description, pre_auth_rsp);
+ /* In success case preauth reassoc is dequeued in
+ * csr_update_roamed_info_mbb before updating HDD.
+ */
+ if(HAL_STATUS_SUCCESS(status))
+ return;
+
+DEQ_PREAUTH:
+ csr_roam_dequeue_preauth_reassoc(mac);
+}
+
+/**
+ * csr_prepare_reassoc_req () - Prepares reassoc request
+ * @pmac: MAC context
+ * @session_id: session id
+ * @pbss_description: bss description
+ * @preassoc_req: pointer to reassociation request
+ *
+ *Return: None
+ */
+static void csr_prepare_reassoc_req(void* pmac, tANI_U32 session_id,
+ void* pbss_description, void *preassoc_req)
+{
+ tDot11fBeaconIEs *ies_local = NULL;
+ eHalStatus status;
+ tpAniSirGlobal mac = (tpAniSirGlobal)pmac;
+ tpSirBssDescription bss_description = (tpSirBssDescription)pbss_description;
+ tSirSmeJoinReq **reassoc_req = (tSirSmeJoinReq **)preassoc_req;
+
+ /* Get IE's */
+ status = csrGetParsedBssDescriptionIEs(mac, bss_description, &ies_local);
+ if (!HAL_STATUS_SUCCESS(status)) {
+ smsLog(mac, LOGE,
+ FL("csrGetParsedBssDescriptionIEs failed"));
+ return;
+ }
+ if(ies_local == NULL) {
+ smsLog(mac, LOGE,
+ FL("ies_local is NULL"));
+ return;
+ }
+
+ smsLog(mac, LOG1, FL("session_id %d"), session_id);
+
+ status = csr_fill_reassoc_req(mac, session_id, bss_description,
+ ies_local, reassoc_req);
+ if (!HAL_STATUS_SUCCESS(status)) {
+ smsLog(mac, LOGE,
+ FL("Reassociation request filling failed"));
+ return;
+ }
+ vos_mem_free(ies_local);
+ smsLog(mac, LOG1, FL("status %d"), status);
+}
+
+/**
+ * csr_roaming_mbb_callback () - handles mbb callback
+ * @pmac: MAC context
+ * @session_id: session id
+ * @pbss_description: bss description
+ * @preassoc_req: pointer to reassociation request
+ * @csr_roam_op_code: callback opcode
+ *
+ *Return: None
+ */
+static void csr_roaming_mbb_callback(void* pmac, tANI_U32 session_id,
+ void* pbss_description, void *preassoc_req, tANI_U32 csr_roam_op_code)
+{
+ tpAniSirGlobal mac = (tpAniSirGlobal)pmac;
+
+ smsLog(mac, LOG1,
+ FL("csr_roam_op_code %d"), csr_roam_op_code);
+
+ switch(csr_roam_op_code) {
+ case SIR_ROAMING_DEREGISTER_STA:
+ csrRoamCallCallback(mac, session_id, NULL, 0,
+ eCSR_ROAM_FT_START, eSIR_SME_SUCCESS);
+ break;
+ case SIR_STOP_ROAM_OFFLOAD_SCAN:
+ csrRoamOffloadScan(mac, ROAM_SCAN_OFFLOAD_STOP, REASON_DISCONNECTED);
+ break;
+ case SIR_PREPARE_REASSOC_REQ:
+ csr_prepare_reassoc_req(pmac, session_id, pbss_description,
+ preassoc_req);
+ break;
+ }
+}
+
+/**
+ * csr_register_roaming_mbb_callback () - registers roaming callback
+ * @mac: MAC context
+ *
+ *Return: eHAL_STATUS_SUCCESS on success, otherwise failure
+ */
+eHalStatus csr_register_roaming_mbb_callback(tpAniSirGlobal mac)
+{
+ eHalStatus status;
+
+ status = sme_AcquireGlobalLock(&mac->sme);
+ if (eHAL_STATUS_SUCCESS == status) {
+ mac->sme.roaming_mbb_callback = csr_roaming_mbb_callback;
+ sme_ReleaseGlobalLock(&mac->sme);
+ } else
+ smsLog(mac, LOGE,
+ FL("sme_AcquireGlobalLock error"));
+ return status;
+}
diff --git a/drivers/staging/prima/CORE/SME/src/pmc/pmc.c b/drivers/staging/prima/CORE/SME/src/pmc/pmc.c
index f87339e92b2..f5539ff6692 100644
--- a/drivers/staging/prima/CORE/SME/src/pmc/pmc.c
+++ b/drivers/staging/prima/CORE/SME/src/pmc/pmc.c
@@ -1584,7 +1584,38 @@ void pmcDoDeviceStateUpdateCallbacks (tHalHandle hHal, tPmcState state)
eHalStatus pmcRequestEnterWowlState(tHalHandle hHal, tpSirSmeWowlEnterParams wowlEnterParams)
{
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
- pmcLog(pMac, LOG1, FL("Enter. PMC State is %d"),pMac->pmc.pmcState);
+ tpPESession pSessionEntry;
+ tANI_U8 peSessionId = 0;
+
+ pSessionEntry = peFindSessionByBssid(pMac, wowlEnterParams->bssId,
+ &peSessionId);
+ if (NULL == pSessionEntry)
+ {
+ pmcLog(pMac, LOGE,
+ FL("session does not exist for given BSSId"));
+
+ if (wowlEnterParams != NULL)
+ vos_mem_free(wowlEnterParams);
+
+ return eHAL_STATUS_FAILURE;
+ }
+
+ pmcLog(pMac, LOG1, FL("Enter. PMC State is %d"),pMac->pmc.pmcState);
+
+ /* Incase of SAP send command directly */
+ if ((pSessionEntry->operMode == BSS_OPERATIONAL_MODE_AP))
+ {
+ if (pmcIssueCommand(hHal, eSmeCommandEnterWowl, wowlEnterParams,
+ sizeof(tSirSmeWowlEnterParams), FALSE) != eHAL_STATUS_SUCCESS)
+ {
+ pmcLog(pMac, LOGE,
+ FL("PMC: failure to send message eWNI_PMC_ENTER_WOWL_REQ"));
+ if (wowlEnterParams != NULL)
+ vos_mem_free(wowlEnterParams);
+ return eHAL_STATUS_FAILURE;
+ }
+ return eHAL_STATUS_SUCCESS;
+ }
switch (pMac->pmc.pmcState)
{
@@ -2069,6 +2100,9 @@ eHalStatus pmcIssueCommand( tpAniSirGlobal pMac, eSmeCommandType cmdType, void *
tANI_BOOLEAN pmcProcessCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand )
{
eHalStatus status = eHAL_STATUS_SUCCESS;
+ tpPESession pSessionEntry;
+ tANI_U8 peSessionId = 0;
+
tANI_BOOLEAN fRemoveCmd = eANI_BOOLEAN_TRUE;
pmcLog(pMac, LOG1, FL("PMC command is 0x%x"), pCommand->command);
do
@@ -2255,7 +2289,13 @@ tANI_BOOLEAN pmcProcessCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand )
case eSmeCommandEnterWowl:
{
tPmcState origState = pMac->pmc.pmcState;
- if( ( BMPS == pMac->pmc.pmcState ) || ( WOWL == pMac->pmc.pmcState ) )
+ pSessionEntry = peFindSessionByBssid(pMac,
+ pCommand->u.pmcCmd.u.enterWowlInfo.bssId,
+ &peSessionId);
+ if (( BMPS == pMac->pmc.pmcState ) ||
+ ( WOWL == pMac->pmc.pmcState ) ||
+ ((pSessionEntry != NULL) &&
+ (pSessionEntry->operMode == BSS_OPERATIONAL_MODE_AP)))
{
pMac->pmc.pmcState = REQUEST_ENTER_WOWL;
status = pmcSendMessage(pMac, eWNI_PMC_ENTER_WOWL_REQ,
diff --git a/drivers/staging/prima/CORE/SME/src/pmc/pmcApi.c b/drivers/staging/prima/CORE/SME/src/pmc/pmcApi.c
index 406317df43f..e46cd350514 100644
--- a/drivers/staging/prima/CORE/SME/src/pmc/pmcApi.c
+++ b/drivers/staging/prima/CORE/SME/src/pmc/pmcApi.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -203,6 +203,7 @@ eHalStatus pmcStart (tHalHandle hHal)
pMac->pmc.uapsdSessionRequired = FALSE;
pMac->pmc.wowlModeRequired = FALSE;
pMac->pmc.wowlExitSrc = eWOWL_EXIT_USER;
+ pMac->pmc.isAPWOWExit = FALSE;
pMac->pmc.bmpsRequestedByHdd = FALSE;
pMac->pmc.remainInPowerActiveTillDHCP = FALSE;
pMac->pmc.full_power_till_set_key = false;
@@ -1239,6 +1240,7 @@ static void pmcProcessResponse( tpAniSirGlobal pMac, tSirSmeRsp *pMsg )
tListElem *pEntry = NULL;
tSmeCmd *pCommand = NULL;
tANI_BOOLEAN fRemoveCommand = eANI_BOOLEAN_TRUE;
+ tCsrRoamSession *pSession = NULL;
pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
if(pEntry)
@@ -1563,11 +1565,25 @@ static void pmcProcessResponse( tpAniSirGlobal pMac, tSirSmeRsp *pMsg )
break;
}
- /* Enter BMPS State */
- if (pMsg->statusCode != eSIR_SME_SUCCESS) {
- pmcLog(pMac, LOGP, "PMC: response message to request to exit "
- "WOWL indicates failure, status %d", pMsg->statusCode);
- }
+ /* Enter BMPS State */
+ if (pMsg->statusCode != eSIR_SME_SUCCESS) {
+ pmcLog(pMac, LOGP, "PMC: response message to request to exit "
+ "WOWL indicates failure, status %d", pMsg->statusCode);
+ }
+
+ pSession = CSR_GET_SESSION(pMac, pMsg->sessionId);
+ if (pSession && pSession->pCurRoamProfile &&
+ CSR_IS_INFRA_AP(pSession->pCurRoamProfile))
+ {
+ pMac->pmc.pmcState = FULL_POWER;
+ pMac->pmc.isAPWOWExit = TRUE;
+ break;
+ }
+ else
+ {
+ pMac->pmc.isAPWOWExit = FALSE;
+ }
+
pmcEnterBmpsState(pMac);
break;
@@ -1779,7 +1795,9 @@ eHalStatus pmcRequestBmps (
/* If DUT exits from WoWL because of wake-up indication then it enters
* into WoWL again. Disable WoWL only when user explicitly disables.
*/
- if(pMac->pmc.wowlModeRequired == FALSE && pMac->pmc.wowlExitSrc == eWOWL_EXIT_WAKEIND)
+ if(pMac->pmc.wowlModeRequired == FALSE &&
+ pMac->pmc.wowlExitSrc == eWOWL_EXIT_WAKEIND &&
+ !pMac->pmc.isAPWOWExit)
{
pMac->pmc.wowlModeRequired = TRUE;
}
@@ -2258,11 +2276,14 @@ eHalStatus pmcWowlAddBcastPattern (
return eHAL_STATUS_FAILURE;
}
- if( !csrIsConnStateConnected(pMac, sessionId) )
+ if (!(CSR_IS_INFRA_AP(pSession->pCurRoamProfile)))
{
- pmcLog(pMac, LOGE, FL("Cannot add WoWL Pattern session in %d state"),
- pSession->connectState);
- return eHAL_STATUS_FAILURE;
+ if( !csrIsConnStateConnected(pMac, sessionId) )
+ {
+ pmcLog(pMac, LOGE, FL("Cannot add WoWL Pattern session in %d state"),
+ pSession->connectState);
+ return eHAL_STATUS_FAILURE;
+ }
}
vos_mem_copy(pattern->bssId, pSession->connectedProfile.bssid, sizeof(tSirMacAddr));
@@ -2448,11 +2469,22 @@ eHalStatus pmcEnterWowl (
return eHAL_STATUS_FAILURE;
}
- /* Check if BMPS is enabled. */
- if (!pMac->pmc.bmpsEnabled)
+ if ((!(CSR_IS_INFRA_AP(pSession->pCurRoamProfile)))
+ && !(vos_get_concurrency_mode()& VOS_STA_SAP))
{
- pmcLog(pMac, LOGE, "PMC: Cannot enter WoWL. BMPS is disabled");
- return eHAL_STATUS_PMC_DISABLED;
+ /* Check if BMPS is enabled. */
+ if (!pMac->pmc.bmpsEnabled)
+ {
+ pmcLog(pMac, LOGE, "PMC: Cannot enter WoWL. BMPS is disabled");
+ return eHAL_STATUS_PMC_DISABLED;
+ }
+ /* Check that we are associated with single Session. */
+ if (!pmcValidateConnectState( pMac ))
+ {
+ pmcLog(pMac, LOGE, "PMC: Cannot enable WOWL. STA not associated "
+ "with an Access Point in Infra Mode with single active session");
+ return eHAL_STATUS_FAILURE;
+ }
}
/* Check if WoWL is enabled. */
@@ -2462,14 +2494,6 @@ eHalStatus pmcEnterWowl (
return eHAL_STATUS_PMC_DISABLED;
}
- /* Check that we are associated with single Session. */
- if (!pmcValidateConnectState( pMac ))
- {
- pmcLog(pMac, LOGE, "PMC: Cannot enable WOWL. STA not associated "
- "with an Access Point in Infra Mode with single active session");
- return eHAL_STATUS_FAILURE;
- }
-
/* Is there a pending UAPSD request? HDD should have triggered QoS
module to do the necessary cleanup before triggring WOWL*/
if(pMac->pmc.uapsdSessionRequired)
diff --git a/drivers/staging/prima/CORE/SME/src/pmc/pmcLogDump.c b/drivers/staging/prima/CORE/SME/src/pmc/pmcLogDump.c
index c8c222fc717..ed9e32b8533 100644
--- a/drivers/staging/prima/CORE/SME/src/pmc/pmcLogDump.c
+++ b/drivers/staging/prima/CORE/SME/src/pmc/pmcLogDump.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -85,6 +85,7 @@ dump_pmc_state( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3
p += log_sprintf( pMac,p, " PMC: RequestFullPowerPending = %d\n", pMac->pmc.requestFullPowerPending);
p += log_sprintf( pMac,p, " PMC: UapsdSessionRequired = %d\n", pMac->pmc.uapsdSessionRequired);
p += log_sprintf( pMac,p, " PMC: wowlModeRequired = %d\n\n", pMac->pmc.wowlModeRequired);
+ p += log_sprintf( pMac,p, " PMC: isAPWOWExit = %d\n\n", pMac->pmc.isAPWOWExit);
pmcLog(pMac, LOGW, "\n%s", ptr);
diff --git a/drivers/staging/prima/CORE/SME/src/sme_common/sme_Api.c b/drivers/staging/prima/CORE/SME/src/sme_common/sme_Api.c
index 05d20d2eae3..5ca51dc7cea 100644
--- a/drivers/staging/prima/CORE/SME/src/sme_common/sme_Api.c
+++ b/drivers/staging/prima/CORE/SME/src/sme_common/sme_Api.c
@@ -73,6 +73,7 @@
#include "sapApi.h"
#include "macTrace.h"
#include "vos_utils.h"
+#include "limSession.h"
extern tSirRetStatus uMacPostCtrlMsg(void* pSirGlobal, tSirMbMsg* pMb);
@@ -803,6 +804,79 @@ eHalStatus sme_process_set_max_tx_power(tpAniSirGlobal pMac,
return eHAL_STATUS_SUCCESS;
}
+/**
+ * sme_process_set_max_tx_power_per_band() - Set the Maximum Transmit Power
+ * specific to band dynamically
+ * @mac_ctx: mac context
+ * @command: cmd param containing band, and power in db
+ *
+ * Set the maximum transmit power dynamically per band
+ *
+ * Return: eHalStatus
+ */
+eHalStatus sme_process_set_max_tx_power_per_band(tpAniSirGlobal mac_ctx,
+ tSmeCmd *command)
+{
+ vos_msg_t msg;
+ tMaxTxPowerPerBandParams *max_tx_params_per_band;
+
+ max_tx_params_per_band =
+ vos_mem_malloc(sizeof(*max_tx_params_per_band));
+ if (max_tx_params_per_band == NULL) {
+ smsLog(mac_ctx, LOGE,
+ FL("fail to allocate memory"));
+ return eHAL_STATUS_FAILURE;
+ }
+
+ max_tx_params_per_band->bandInfo =
+ command->u.set_tx_max_pwr_per_band.band;
+ max_tx_params_per_band->power =
+ command->u.set_tx_max_pwr_per_band.power;
+
+ msg.type = WDA_SET_MAX_TX_POWER_PER_BAND_REQ;
+ msg.reserved = 0;
+ msg.bodyptr = max_tx_params_per_band;
+
+ if (VOS_STATUS_SUCCESS !=
+ vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) {
+ smsLog(mac_ctx, LOGE,
+ FL("Unable to post message to WDA"));
+ vos_mem_free(max_tx_params_per_band);
+ return eHAL_STATUS_FAILURE;
+ }
+ return eHAL_STATUS_SUCCESS;
+}
+
+
+/**
+ * sme_process_update_channel_list() - Update channel list
+ * @mac_ctx: mac context
+ * @command: cmd param containing band, and power in db
+ *
+ * Return: eHalStatus
+ */
+eHalStatus sme_process_update_channel_list(tpAniSirGlobal mac_ctx,
+ tSmeCmd *command)
+{
+ vos_msg_t msg;
+
+ msg.type = WDA_UPDATE_CHAN_LIST_REQ;
+ msg.reserved = 0;
+ msg.bodyptr = command->u.chan_list;
+
+ MTRACE(vos_trace(VOS_MODULE_ID_SME,
+ TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, msg.type));
+
+ if (VOS_STATUS_SUCCESS !=
+ vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) {
+ smsLog(mac_ctx, LOGE,
+ FL("Unable to post message to WDA"));
+ vos_mem_free(command->u.chan_list);
+ return eHAL_STATUS_FAILURE;
+ }
+ return eHAL_STATUS_SUCCESS;
+}
+
static void smeProcessNanReq(tpAniSirGlobal pMac, tSmeCmd *pCommand )
{
tSirMsgQ msgQ;
@@ -1087,6 +1161,32 @@ sme_process_cmd:
}
pMac->max_power_cmd_pending = false;
break;
+ case eSmeCommandSetMaxTxPowerPerBand:
+ csrLLUnlock(&pMac->sme.smeCmdActiveList);
+ sme_process_set_max_tx_power_per_band(pMac,
+ pCommand);
+ /* We need to re-run the command */
+ fContinue = eANI_BOOLEAN_TRUE;
+ /* No Rsp expected, free cmd from active list */
+ if (csrLLRemoveEntry(&pMac->sme.smeCmdActiveList,
+ &pCommand->Link, LL_ACCESS_LOCK)) {
+ csrReleaseCommand(pMac, pCommand);
+ }
+ pMac->max_power_cmd_pending = false;
+ break;
+
+ case eSmeCommandUpdateChannelList:
+ csrLLUnlock(&pMac->sme.smeCmdActiveList);
+ sme_process_update_channel_list(pMac, pCommand);
+ if (csrLLRemoveEntry(&pMac->sme.smeCmdActiveList,
+ &pCommand->Link, LL_ACCESS_LOCK)) {
+ csrReleaseCommand(pMac, pCommand);
+ }
+ smsLog(pMac, LOG1,
+ FL("eSmeCommandUpdateChannelList processed"));
+ fContinue = eANI_BOOLEAN_TRUE;
+ break;
+
#ifdef FEATURE_OEM_DATA_SUPPORT
case eSmeCommandOemDataReq:
csrLLUnlock(&pMac->sme.smeCmdActiveList);
@@ -1437,6 +1537,7 @@ eHalStatus sme_Open(tHalHandle hHal)
#if defined WLAN_FEATURE_VOWIFI_11R
sme_FTOpen(pMac);
#endif
+
sme_p2pOpen(pMac);
smeTraceInit(pMac);
sme_register_debug_callback();
@@ -1671,6 +1772,9 @@ eHalStatus sme_UpdateConfig(tHalHandle hHal, tpSmeConfigParams pSmeConfigParams)
pMac->fDeferIMPSTime = pSmeConfigParams->fDeferIMPSTime;
pMac->fBtcEnableIndTimerVal = pSmeConfigParams->fBtcEnableIndTimerVal;
+ pMac->sta_auth_retries_for_code17 =
+ pSmeConfigParams->csrConfig.sta_auth_retries_for_code17;
+
return status;
}
@@ -2481,12 +2585,16 @@ eHalStatus sme_ProcessMsg(tHalHandle hHal, vos_msg_t* pMsg)
smsLog( pMac, LOG1, FL("SIR_COEX_IND_TYPE_DISABLE_AGGREGATION_IN_2p4"));
sme_RequestFullPower(hHal, NULL, NULL, eSME_REASON_OTHER);
pMac->isCoexScoIndSet = 1;
+ pMac->scan.fRestartIdleScan = eANI_BOOLEAN_FALSE;
+ pMac->scan.fCancelIdleScan = eANI_BOOLEAN_TRUE;
}
else if (pSmeCoexInd->coexIndType == SIR_COEX_IND_TYPE_ENABLE_AGGREGATION_IN_2p4)
{
smsLog( pMac, LOG1, FL("SIR_COEX_IND_TYPE_ENABLE_AGGREGATION_IN_2p4"));
pMac->isCoexScoIndSet = 0;
sme_RequestBmps(hHal, NULL, NULL);
+ pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE;
+ pMac->scan.fCancelIdleScan = eANI_BOOLEAN_FALSE;
}
status = btcHandleCoexInd((void *)pMac, pMsg->bodyptr);
@@ -3720,7 +3828,13 @@ eHalStatus sme_RoamDisconnect(tHalHandle hHal, tANI_U8 sessionId, eCsrRoamDiscon
{
if( CSR_IS_SESSION_VALID( pMac, sessionId ) )
{
- status = csrRoamDisconnect( pMac, sessionId, reason );
+ /*
+ * Indicate csr of disconnect so that
+ * in progress connection, scan for ssid and preauth
+ * can be aborted
+ */
+ csr_abortConnection(pMac, sessionId);
+ status = csrRoamDisconnect(pMac, sessionId, reason);
}
else
{
@@ -5212,7 +5326,6 @@ eHalStatus sme_RoamSetKey(tHalHandle hHal, tANI_U8 sessionId, tCsrRoamSetKey *pS
smsLog(pMac, LOGE, FL("Invalid key length %d"), pSetKey->keyLength);
return eHAL_STATUS_FAILURE;
}
-
status = sme_AcquireGlobalLock( &pMac->sme );
if ( HAL_STATUS_SUCCESS( status ) )
{
@@ -5240,6 +5353,15 @@ eHalStatus sme_RoamSetKey(tHalHandle hHal, tANI_U8 sessionId, tCsrRoamSetKey *pS
if(CSR_IS_INFRA_AP(&pSession->connectedProfile))
{
+#ifdef SAP_AUTH_OFFLOAD
+ if (pMac->sap_auth_offload_sec_type)
+ {
+ smsLog(pMac, LOGE,
+ FL("No set key is required in sap auth offload enable"));
+ sme_ReleaseGlobalLock(&pMac->sme);
+ return eHAL_STATUS_SUCCESS;
+ }
+#endif
if(pSetKey->keyDirection == eSIR_TX_DEFAULT)
{
if ( ( eCSR_ENCRYPT_TYPE_WEP40 == pSetKey->encType ) ||
@@ -9168,7 +9290,7 @@ eHalStatus sme_8023MulticastList (tHalHandle hHal, tANI_U8 sessionId, tpSirRcvFl
if(pSession == NULL )
{
- VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Unable to find "
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, "%s: Unable to find "
"the right session", __func__);
return eHAL_STATUS_FAILURE;
}
@@ -9625,51 +9747,61 @@ eHalStatus sme_SetMaxTxPower(tHalHandle hHal, tSirMacAddr bssid,
return (status);
}
-/* ---------------------------------------------------------------------------
-
- \fn sme_SetMaxTxPowerPerBand
-
- \brief Set the Maximum Transmit Power specific to band dynamically.
- Note: this setting will not persist over reboots.
-
- \param band
- \param power to set in dB
- \- return eHalStatus
-
- ----------------------------------------------------------------------------*/
-eHalStatus sme_SetMaxTxPowerPerBand(eCsrBand band, v_S7_t dB)
+/**
+ * sme_SetMaxTxPowerPerBand() - Set the Maximum Transmit Power
+ * specific to band dynamically
+ * @band: Band for which power needs to be applied
+ * @dB: power to set in dB
+ * @hal: HAL handle
+ *
+ * Set the maximum transmit power dynamically per band
+ *
+ * Return: eHalStatus
+ */
+eHalStatus sme_SetMaxTxPowerPerBand(eCsrBand band, v_S7_t dB,
+ tHalHandle hal)
{
vos_msg_t msg;
- tpMaxTxPowerPerBandParams pMaxTxPowerPerBandParams = NULL;
+ eHalStatus status;
+ tSmeCmd *set_max_tx_pwr_per_band;
+ tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
- pMaxTxPowerPerBandParams = vos_mem_malloc(sizeof(tMaxTxPowerPerBandParams));
- if (NULL == pMaxTxPowerPerBandParams)
- {
- VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
- "%s:Not able to allocate memory for pMaxTxPowerPerBandParams",
- __func__);
- return eHAL_STATUS_FAILURE;
- }
+ if (mac_ctx->max_power_cmd_pending)
+ {
+ smsLog(mac_ctx, LOG1,
+ FL("set max tx power already in progress"));
+ return eHAL_STATUS_RESOURCES;
+ }
- pMaxTxPowerPerBandParams->power = dB;
- pMaxTxPowerPerBandParams->bandInfo = band;
+ smsLog(mac_ctx, LOG1,
+ FL("band : %d power %d dB"),
+ band, dB);
- msg.type = WDA_SET_MAX_TX_POWER_PER_BAND_REQ;
- msg.reserved = 0;
- msg.bodyptr = pMaxTxPowerPerBandParams;
+ MTRACE(vos_trace(VOS_MODULE_ID_SME,
+ TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, msg.type));
- MTRACE(vos_trace(VOS_MODULE_ID_SME,
- TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, msg.type));
- if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))
- {
- VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
- "%s:Not able to post WDA_SET_MAX_TX_POWER_PER_BAND_REQ",
- __func__);
- vos_mem_free(pMaxTxPowerPerBandParams);
- return eHAL_STATUS_FAILURE;
+ status = sme_AcquireGlobalLock(&mac_ctx->sme);
+ if (HAL_STATUS_SUCCESS(status)) {
+ set_max_tx_pwr_per_band = csrGetCommandBuffer(mac_ctx);
+ if (set_max_tx_pwr_per_band) {
+ set_max_tx_pwr_per_band->command = eSmeCommandSetMaxTxPowerPerBand;
+ set_max_tx_pwr_per_band->u.set_tx_max_pwr_per_band.band = band;
+ set_max_tx_pwr_per_band->u.set_tx_max_pwr_per_band.power = dB;
+ mac_ctx->max_power_cmd_pending = true;
+ status = csrQueueSmeCommand(mac_ctx, set_max_tx_pwr_per_band,
+ eANI_BOOLEAN_TRUE);
+ if (!HAL_STATUS_SUCCESS(status)) {
+ smsLog(mac_ctx, LOGE, FL("fail to send msg status = %d"), status);
+ csrReleaseCommand(mac_ctx, set_max_tx_pwr_per_band);
+ mac_ctx->max_power_cmd_pending = false;
+ }
+ } else {
+ smsLog(mac_ctx, LOGE, FL("can not obtain a common buffer"));
+ status = eHAL_STATUS_RESOURCES;
+ }
+ sme_ReleaseGlobalLock(&mac_ctx->sme);
}
-
- return eHAL_STATUS_SUCCESS;
+ return status;
}
/* ---------------------------------------------------------------------------
@@ -14416,96 +14548,545 @@ eHalStatus sme_get_nud_debug_stats(tHalHandle hHal,
return VOS_STATUS_SUCCESS;
}
-eHalStatus sme_test_con_alive(tHalHandle hHal)
+
+#ifdef SAP_AUTH_OFFLOAD
+/**
+ * sme_set_sap_auth_offload() enable/disable Software AP Auth Offload
+ * @hHal: hal layer handler
+ * @sap_auth_offload_info: the information of Software AP Auth offload
+ *
+ * This function provide enable/disable Software AP authenticaiton offload
+ * feature on target firmware
+ *
+ * Return: Return eHalStatus.
+ */
+eHalStatus sme_set_sap_auth_offload(tHalHandle hHal,
+ struct tSirSapOffloadInfo *sap_auth_offload_info)
{
- vos_msg_t wdaMsg = {0};
+ vos_msg_t vosMessage;
+ struct tSirSapOffloadInfo *sme_sap_auth_offload_info;
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
- wdaMsg.type = WDA_TRIGGER_ADD_BA_REQ;
- wdaMsg.bodyptr = NULL;
- wdaMsg.reserved = 0;
+ pMac->sap_auth_offload_sec_type =
+ sap_auth_offload_info->sap_auth_offload_sec_type;
+ pMac->sap_auth_offload = sap_auth_offload_info->sap_auth_offload_enable;
- if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_WDA, &wdaMsg))
- return VOS_STATUS_E_FAILURE;
+ sme_sap_auth_offload_info =
+ vos_mem_malloc(sizeof(*sme_sap_auth_offload_info));
- return VOS_STATUS_SUCCESS;
+ if (!sme_sap_auth_offload_info)
+ {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ "%s: Not able to allocate memory for WDA_SET_SAP_AUTH_OFL",
+ __func__);
+ return eHAL_STATUS_E_MALLOC_FAILED;
+ }
+ vos_mem_copy(sme_sap_auth_offload_info, sap_auth_offload_info,
+ sizeof(*sap_auth_offload_info));
+
+ if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme)))
+ {
+ /* serialize the req through MC thread */
+ vosMessage.type = WDA_SET_SAP_AUTH_OFL;
+ vosMessage.bodyptr = sme_sap_auth_offload_info;
+
+ if (!VOS_IS_STATUS_SUCCESS(
+ vos_mq_post_message(VOS_MODULE_ID_WDA, &vosMessage)))
+ {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ "%s: Not able to post WDA_SET_SAP_AUTH_OFL to WDA!",
+ __func__);
+ vos_mem_free(sme_sap_auth_offload_info);
+ status = eHAL_STATUS_FAILURE;
+ }
+ sme_ReleaseGlobalLock(&pMac->sme);
+ }
+ else
+ {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ "%s: sme_AcquireGlobalLock error!",
+ __func__);
+ vos_mem_free(sme_sap_auth_offload_info);
+ status = eHAL_STATUS_FAILURE;
+ }
+
+ return (status);
}
+#endif
+#ifdef DHCP_SERVER_OFFLOAD
+/**
+ * sme_set_dhcp_srv_offload() - sme api to set dhcp server offload info
+ * @hal: handle to hal
+ * @dhcp_srv_info: pointer to dhcp server info
+ *
+ * Return: eHalStatus
+ * eHAL_STATUS_SUCCESS - success or else failure code
+ */
+eHalStatus sme_set_dhcp_srv_offload(tHalHandle hal,
+ sir_dhcp_srv_offload_info_t *dhcp_srv_info)
+{
+ vos_msg_t vos_msg;
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ tpAniSirGlobal mac = PMAC_STRUCT(hal);
+ sir_dhcp_srv_offload_info_t *dhcp_serv_info = NULL;
+
+ dhcp_serv_info =
+ vos_mem_malloc(sizeof(*dhcp_serv_info));
+ if (NULL == dhcp_serv_info) {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ "Failed to alloc memory");
+ return VOS_STATUS_E_NOMEM;
+ }
+
+ vos_mem_copy(dhcp_serv_info, dhcp_srv_info,
+ sizeof(*dhcp_serv_info));
+
+ dhcp_serv_info->bssidx = peFindBssIdxFromSmeSessionId(mac, dhcp_srv_info->bssidx);
+ status = sme_AcquireGlobalLock(&mac->sme);
+ if (eHAL_STATUS_SUCCESS == status) {
+ /* serialize the req through MC thread */
+ vos_msg.type = WDA_SET_DHCP_SERVER_OFFLOAD_REQ;
+ vos_msg.bodyptr = dhcp_serv_info;
+
+ if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message
+ (VOS_MODULE_ID_WDA, &vos_msg))) {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ "%s: Not able to post WDA_SET_DHCP_SERVER_OFFLOAD_REQ to WDA!",
+ __func__);
+ vos_mem_free(dhcp_serv_info);
+ status = eHAL_STATUS_FAILURE;
+ }
+ sme_ReleaseGlobalLock(&mac->sme);
+ } else {
+ VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ "%s: sme_AcquireGlobalLock error!",
+ __func__);
+ vos_mem_free(dhcp_serv_info);
+ }
+
+ return status;
+}
+#endif /* DHCP_SERVER_OFFLOAD */
+
+#ifdef MDNS_OFFLOAD
+/**
+ * sme_set_mdns_offload() - sme API to set mdns offload enable/disable
+ * @hal: handle to hal pointer
+ * @mdns_info: pointer to mdns offload info
+ *
+ * Return - eHalStatus
+ */
+eHalStatus sme_set_mdns_offload(tHalHandle hal,
+ sir_mdns_offload_info_t *mdns_info)
+{
+ vos_msg_t vos_msg;
+ sir_mdns_offload_info_t *mdns_offload;
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ tpAniSirGlobal mac = PMAC_STRUCT(hal);
+
+ mdns_offload = vos_mem_malloc(sizeof(*mdns_offload));
+
+ if (!mdns_offload) {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ "%s: Not able to allocate memory for WDA_SET_MDNS_OFFLOAD_CMD",
+ __func__);
+ return eHAL_STATUS_E_MALLOC_FAILED;
+ }
-eHalStatus sme_get_con_alive(tHalHandle hHal,
- pgetConStatusParams conStatusParams)
+ vos_mem_copy(mdns_offload, mdns_info, sizeof(*mdns_offload));
+ mdns_offload->bss_idx =
+ peFindBssIdxFromSmeSessionId(mac, mdns_info->bss_idx);
+ status = sme_AcquireGlobalLock(&mac->sme);
+ if (eHAL_STATUS_SUCCESS == status) {
+ /* serialize the req through MC thread */
+ vos_msg.type = WDA_SET_MDNS_OFFLOAD_CMD;
+ vos_msg.bodyptr = mdns_offload;
+
+ if (!VOS_IS_STATUS_SUCCESS(
+ vos_mq_post_message(VOS_MODULE_ID_WDA,
+ &vos_msg))) {
+ VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ "%s: Not able to post WDA_SET_MDNS_OFFLOAD_CMD to WDA!",
+ __func__);
+ vos_mem_free(mdns_offload);
+ status = eHAL_STATUS_FAILURE;
+ }
+ sme_ReleaseGlobalLock(&mac->sme);
+ } else {
+ VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ "%s: sme_AcquireGlobalLock error!",
+ __func__);
+ vos_mem_free(mdns_offload);
+ }
+
+ return (status);
+}
+
+/**
+ * sme_set_mdns_fqdn() - SME API to set mDNS Fqdn info
+ * @hal: hal handle
+ * @mdns_fqdn: mDNS Fqdn info struct
+ *
+ * Return - return eHalStatus
+ */
+eHalStatus sme_set_mdns_fqdn(tHalHandle hal,
+ sir_mdns_fqdn_info_t *mdns_fqdn)
{
- vos_msg_t wdaMsg = {0};
- pgetConStatusParams statusParams;
- VOS_STATUS vosStatus;
+ vos_msg_t vos_msg;
+ sir_mdns_fqdn_info_t *fqdn_info;
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ tpAniSirGlobal mac = PMAC_STRUCT(hal);
- statusParams = vos_mem_malloc(sizeof(getConStatusParams));
- if (NULL == statusParams) {
- VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
- FL("Memory allocation failure"));
- return VOS_STATUS_E_NOMEM;
- }
+ fqdn_info = vos_mem_malloc(sizeof(*fqdn_info));
- vos_mem_copy(statusParams, conStatusParams, sizeof(getConStatusParams));
- wdaMsg.type = WDA_GET_CON_STATUS;
- wdaMsg.bodyptr = statusParams;
- wdaMsg.reserved = 0;
+ if (!fqdn_info) {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ "%s: Not able to allocate memory for WDA_SET_MDNS_FQDN_CMD",
+ __func__);
+ return eHAL_STATUS_E_MALLOC_FAILED;
+ }
- vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &wdaMsg);
- if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
- VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
- FL(" Not able to post message"));
- vos_mem_free(statusParams);
- return VOS_STATUS_E_FAILURE;
- }
+ vos_mem_copy(fqdn_info, mdns_fqdn, sizeof(*fqdn_info));
+ fqdn_info->bss_idx = peFindBssIdxFromSmeSessionId(mac, mdns_fqdn->bss_idx);
+ status = sme_AcquireGlobalLock(&mac->sme);
+ if (eHAL_STATUS_SUCCESS == status) {
+ /* serialize the req through MC thread */
+ vos_msg.type = WDA_SET_MDNS_FQDN_CMD;
+ vos_msg.bodyptr = fqdn_info;
+
+ if (!VOS_IS_STATUS_SUCCESS(
+ vos_mq_post_message(VOS_MODULE_ID_WDA,
+ &vos_msg))) {
+ VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ "%s: Not able to post WDA_SET_MDNS_FQDN_CMD to WDA!",
+ __func__);
+ vos_mem_free(fqdn_info);
+ status = eHAL_STATUS_FAILURE;
+ }
+ sme_ReleaseGlobalLock(&mac->sme);
+ } else {
+ VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ "%s: sme_AcquireGlobalLock error!",
+ __func__);
+ vos_mem_free(fqdn_info);
+ }
- return VOS_STATUS_SUCCESS;
+ return (status);
}
-eHalStatus sme_test_con_delba(tHalHandle hHal, uint8_t sta_id,
- uint8_t session_id)
+/**
+ * sme_set_mdns_resp() - SME API to set mDNS response info
+ * @hal: hal handle
+ * @mdns_resp : mDNS response info struct
+ *
+ * Return - eHalStatus
+ */
+eHalStatus sme_set_mdns_resp(tHalHandle hal,
+ sir_mdns_resp_info_t *mdns_resp)
{
- tpSmeDelBAPeerInd msg;
- tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
- tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, session_id);
- eHalStatus status = eHAL_STATUS_FAILURE;
+ vos_msg_t vos_msg;
+ sir_mdns_resp_info_t *resp_info;
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ tpAniSirGlobal mac = PMAC_STRUCT(hal);
- if (!CSR_IS_SESSION_VALID(pMac, session_id))
- {
- VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
- FL("Session is invalid"));
- return status;
- }
+ resp_info = vos_mem_malloc(sizeof(*resp_info));
- if (!pMac->lim.test_status_bainfo.tx_aggr)
- {
- VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
- FL("BA session not established"));
- return status;
- }
+ if (!resp_info) {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ "%s: Not able to allocate memory for WDA_SET_MDNS_RESPONSE_CMD",
+ __func__);
+ return eHAL_STATUS_E_MALLOC_FAILED;
+ }
- if (eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock(&pMac->sme))
- {
- msg = vos_mem_malloc(sizeof(tSmeDelBAPeerInd));
- if (NULL == msg)
- {
- VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ vos_mem_copy(resp_info, mdns_resp, sizeof(*resp_info));
+ resp_info->bss_idx = peFindBssIdxFromSmeSessionId(mac, mdns_resp->bss_idx);
+ status = sme_AcquireGlobalLock(&mac->sme);
+ if (eHAL_STATUS_SUCCESS == status) {
+ /* serialize the req through MC thread */
+ vos_msg.type = WDA_SET_MDNS_RESPONSE_CMD;
+ vos_msg.bodyptr = resp_info;
+
+ if (!VOS_IS_STATUS_SUCCESS(
+ vos_mq_post_message(VOS_MODULE_ID_WDA,
+ &vos_msg))) {
+ VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ "%s: Not able to post WDA_SET_MDNS_RESPONSE_CMD to WDA!",
+ __func__);
+ vos_mem_free(resp_info);
+ status = eHAL_STATUS_FAILURE;
+ }
+ sme_ReleaseGlobalLock(&mac->sme);
+ } else {
+ VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ "%s: sme_AcquireGlobalLock error!",
+ __func__);
+ vos_mem_free(resp_info);
+ }
+
+ return (status);
+}
+#endif /* MDNS_OFFLOAD */
+
+/**
+ * sme_update_hb_threshold() - Set heartbeat Threshold value.
+ * @hal: HAL pointer
+ * @cfgId: cfg param id
+ * @hbThresh: heartbeat threshold value.
+ *
+ * Return: Success/Failure
+ */
+eHalStatus sme_update_hb_threshold(tHalHandle hHal, tANI_U32 cfgId,
+ tANI_U8 hbThresh, eCsrBand eBand)
+{
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+ if ((hbThresh < WNI_CFG_HEART_BEAT_THRESHOLD_STAMIN) ||
+ (hbThresh > WNI_CFG_HEART_BEAT_THRESHOLD_STAMAX)) {
+ smsLog(pMac, LOGE, FL("invalid heartbeat threshold %hhu"), hbThresh);
+ return eHAL_STATUS_FAILURE;
+ }
+
+ if(eBand == eCSR_BAND_24)
+ pMac->roam.configParam.HeartbeatThresh24 = hbThresh;
+
+ if(eBand == eCSR_BAND_5G)
+ pMac->roam.configParam.HeartbeatThresh50 = hbThresh;
+
+ status = sme_update_cfg_int_param(hHal, WNI_CFG_HEART_BEAT_THRESHOLD);
+ if (eHAL_STATUS_SUCCESS != status) {
+ smsLog(pMac, LOGE, FL("WLAN set heartbeat threshold FAILED"));
+ status = eHAL_STATUS_FAILURE;
+ }
+ return status;
+}
+
+#ifdef WLAN_FEATURE_APFIND
+/**
+ * sme_apfind_set_cmd() - set apfind configuration to firmware
+ * @input: pointer to apfind request data.
+ *
+ * SME API to set APFIND configuations to firmware.
+ *
+ * Return: VOS_STATUS.
+ */
+VOS_STATUS sme_apfind_set_cmd(struct sme_ap_find_request_req *input)
+{
+ vos_msg_t msg;
+ struct hal_apfind_request *data;
+ size_t data_len;
+
+ data_len = sizeof(struct hal_apfind_request) + input->request_data_len;
+ data = vos_mem_malloc(data_len);
+
+ if (data == NULL) {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
FL("Memory allocation failure"));
- return VOS_STATUS_E_NOMEM;
- }
+ return VOS_STATUS_E_NOMEM;
+ }
- msg->staIdx = sta_id;
- msg->baTID = pMac->lim.test_status_bainfo.tid;
- vos_mem_copy(msg->bssId, pSession->connectedProfile.bssid,
- sizeof(tSirMacAddr));
- msg->baDirection = eBA_INITIATOR;
+ vos_mem_zero(data, data_len);
+ data->request_data_len = input->request_data_len;
+ if (input->request_data_len) {
+ vos_mem_copy(data->request_data,
+ input->request_data, input->request_data_len);
+ }
- msg->mesgType = eWNI_SME_DEL_TEST_BA;
- msg->mesgLen = sizeof(tSmeDelBAPeerInd);
+ msg.type = WDA_APFIND_SET_CMD;
+ msg.reserved = 0;
+ msg.bodyptr = data;
- status = palSendMBMessage(pMac->hHdd, msg);
+ if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ FL("Not able to post WDA_APFIND_SET_CMD message to WDA"));
+ vos_mem_free(data);
+ return VOS_STATUS_E_FAILURE;
+ }
- sme_ReleaseGlobalLock(&pMac->sme);
- }
+ return VOS_STATUS_SUCCESS;
+}
- return status;
+#endif /* WLAN_FEATURE_APFIND */
+
+/**
+ * sme_capture_tsf_req() - send tsf capture request to firmware
+ * @hHal: hal handle.
+ * @cap_tsf_params: capture tsf request params.
+ *
+ * Return: hal status.
+ */
+eHalStatus sme_capture_tsf_req(tHalHandle hHal, tSirCapTsfParams cap_tsf_params)
+{
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+ vos_msg_t vosMessage;
+ tpSirCapTsfParams tsf_params = NULL;
+ VOS_STATUS vos_status;
+ tCsrRoamSession *pSession;
+
+ MTRACE(vos_trace(VOS_MODULE_ID_SME,
+ TRACE_CODE_SME_TX_HDD_CAP_TSF_REQ, NO_SESSION, 0));
+ if (eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock(&pMac->sme)))
+ {
+ pSession = CSR_GET_SESSION(pMac, cap_tsf_params.session_id);
+ if (!pSession)
+ {
+ smsLog(pMac, LOGE, FL("session %d not found"),
+ cap_tsf_params.bss_idx);
+ sme_ReleaseGlobalLock( &pMac->sme );
+ return eHAL_STATUS_FAILURE;
+ }
+
+ tsf_params = (tpSirCapTsfParams)
+ vos_mem_malloc(sizeof(*tsf_params));
+
+ if (NULL == tsf_params)
+ {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ "%s: Not able to allocate memory for sme_capture_tsf_req",
+ __func__);
+ sme_ReleaseGlobalLock( &pMac->sme );
+ return eHAL_STATUS_FAILURE;
+ }
+ vos_mem_copy(&tsf_params->bssid, &pSession->connectedProfile.bssid,
+ sizeof(tsf_params->bssid));
+
+ tsf_params->tsf_rsp_cb_func = cap_tsf_params.tsf_rsp_cb_func;
+ tsf_params->tsf_rsp_cb_ctx = cap_tsf_params.tsf_rsp_cb_ctx;
+
+ /* serialize the req through MC thread */
+ /* TODO: check if callback is required */
+ vosMessage.bodyptr = tsf_params;
+ vosMessage.type = eWNI_SME_CAP_TSF_REQ;
+
+ vos_status = vos_mq_post_message(VOS_MQ_ID_PE, &vosMessage);
+
+ if (!VOS_IS_STATUS_SUCCESS(vos_status))
+ {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ "%s: Post Set TM Level MSG fail", __func__);
+ vos_mem_free(tsf_params);
+ status = eHAL_STATUS_FAILURE;
+ }
+ sme_ReleaseGlobalLock( &pMac->sme );
+ }
+ return(status);
+}
+
+eHalStatus sme_del_sta_ba_session_req(tHalHandle hHal,
+ tDelBaParams sta_del_params)
+{
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+ vos_msg_t vosMessage;
+ ptDelBaParams del_params = NULL;
+ VOS_STATUS vos_status;
+ tCsrRoamSession *pSession;
+
+ MTRACE(vos_trace(VOS_MODULE_ID_SME,
+ TRACE_CODE_SME_DEL_STA_BA_SESSION_REQ, NO_SESSION, 0));
+ if (eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock(&pMac->sme)))
+ {
+ pSession = CSR_GET_SESSION(pMac, sta_del_params.session_id);
+ if (!pSession)
+ {
+ smsLog(pMac, LOGE, FL("session not found"));
+ sme_ReleaseGlobalLock( &pMac->sme );
+ return eHAL_STATUS_FAILURE;
+ }
+
+ del_params = (ptDelBaParams) vos_mem_malloc(sizeof(*del_params));
+
+ if (NULL == del_params)
+ {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ "%s: Not able to allocate memory for sme_del_sta_ba_session_req", __func__);
+ sme_ReleaseGlobalLock( &pMac->sme );
+ return eHAL_STATUS_FAILURE;
+ }
+ vos_mem_copy(&del_params->session_id, &pSession->sessionId,
+ sizeof(del_params->session_id));
+
+ vosMessage.bodyptr = del_params;
+ vosMessage.type = eWNI_SME_DEL_BA_SES_REQ;
+
+ vos_status = vos_mq_post_message(VOS_MQ_ID_PE, &vosMessage);
+
+ if (!VOS_IS_STATUS_SUCCESS(vos_status))
+ {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ "%s: Post Set TM Level MSG fail", __func__);
+ vos_mem_free(del_params);
+ status = eHAL_STATUS_FAILURE;
+ }
+ sme_ReleaseGlobalLock( &pMac->sme );
+ }
+ return(status);
+}
+
+/**
+ * sme_get_tsf_req() - send tsf get request to firmware
+ * @hHal: hal handle.
+ * @cap_tsf_params: capture tsf request params.
+ *
+ * Return: hal status.
+ */
+eHalStatus sme_get_tsf_req(tHalHandle hHal, tSirCapTsfParams cap_tsf_params)
+{
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+ vos_msg_t vosMessage;
+ tpSirCapTsfParams tsf_params = NULL;
+ VOS_STATUS vosStatus;
+ tCsrRoamSession *pSession;
+
+ MTRACE(vos_trace(VOS_MODULE_ID_SME,
+ TRACE_CODE_SME_TX_HDD_GET_TSF_REQ, NO_SESSION, 0));
+
+ if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme)))
+ {
+ pSession = CSR_GET_SESSION(pMac, cap_tsf_params.session_id);
+
+ if (!pSession)
+ {
+ smsLog(pMac, LOGE, FL("session %d not found"),
+ cap_tsf_params.bss_idx);
+ sme_ReleaseGlobalLock(&pMac->sme);
+ return eHAL_STATUS_FAILURE;
+ }
+
+ tsf_params = (tpSirCapTsfParams)
+ vos_mem_malloc(sizeof(*tsf_params));
+ if (NULL == tsf_params)
+ {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ "%s: Not able to allocate memory for sme_capture_tsf_req",
+ __func__);
+ sme_ReleaseGlobalLock(&pMac->sme);
+ return eHAL_STATUS_FAILURE;
+ }
+
+ vos_mem_copy(&tsf_params->bssid, &pSession->connectedProfile.bssid,
+ sizeof(tsf_params->bssid));
+ tsf_params->tsf_rsp_cb_func = cap_tsf_params.tsf_rsp_cb_func;
+ tsf_params->tsf_rsp_cb_ctx = cap_tsf_params.tsf_rsp_cb_ctx;
+
+ /* serialize the req through MC thread */
+ /* TODO: check if callback is required */
+ vosMessage.bodyptr = tsf_params;
+ vosMessage.type = eWNI_SME_GET_TSF_REQ;
+
+ vosStatus = vos_mq_post_message(VOS_MQ_ID_PE, &vosMessage);
+ if (!VOS_IS_STATUS_SUCCESS(vosStatus))
+ {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ "%s: Post Set TM Level MSG fail", __func__);
+ vos_mem_free(tsf_params);
+ status = eHAL_STATUS_FAILURE;
+ }
+ sme_ReleaseGlobalLock(&pMac->sme);
+ }
+ return(status);
}
diff --git a/drivers/staging/prima/CORE/SME/src/sme_common/sme_FTApi.c b/drivers/staging/prima/CORE/SME/src/sme_common/sme_FTApi.c
index 4d988afb85f..fef98d3dd8c 100644
--- a/drivers/staging/prima/CORE/SME/src/sme_common/sme_FTApi.c
+++ b/drivers/staging/prima/CORE/SME/src/sme_common/sme_FTApi.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014, 2016-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -41,6 +41,11 @@
#include <csrNeighborRoam.h>
#include "vos_utils.h"
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "csr_roam_mbb.h"
+#endif
+
+
/*--------------------------------------------------------------------------
Initialize the FT context.
------------------------------------------------------------------------*/
@@ -60,6 +65,18 @@ void sme_FTOpen(tHalHandle hHal)
return;
}
vos_reset_roam_timer_log();
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ status = vos_timer_init(&pMac->ft.ftSmeContext.pre_auth_reassoc_mbb_timer,
+ VOS_TIMER_TYPE_SW,
+ csr_preauth_reassoc_mbb_timer_callback,
+ (void *)pMac);
+
+ if (eHAL_STATUS_SUCCESS != status) {
+ smsLog(pMac, LOGE, FL("pre_auth_reassoc_mbb_timer allocation failed"));
+ return;
+ }
+#endif
}
/*--------------------------------------------------------------------------
@@ -71,6 +88,10 @@ void sme_FTClose(tHalHandle hHal)
//Clear the FT Context.
sme_FTReset(hHal);
vos_timer_destroy(&pMac->ft.ftSmeContext.preAuthReassocIntvlTimer);
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ vos_timer_destroy(&pMac->ft.ftSmeContext.pre_auth_reassoc_mbb_timer);
+#endif
}
void sme_SetFTPreAuthState(tHalHandle hHal, v_BOOL_t state)
@@ -116,6 +137,9 @@ void sme_SetFTIEs( tHalHandle hHal, tANI_U8 sessionId, const tANI_U8 *ft_ies,
{
case eFT_START_READY:
case eFT_AUTH_REQ_READY:
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ smsLog( pMac, LOG1, FL("ft_ies_length: %d"), ft_ies_length);
+#endif
if ((pMac->ft.ftSmeContext.auth_ft_ies) &&
(pMac->ft.ftSmeContext.auth_ft_ies_length))
{
@@ -123,7 +147,7 @@ void sme_SetFTIEs( tHalHandle hHal, tANI_U8 sessionId, const tANI_U8 *ft_ies,
vos_mem_free(pMac->ft.ftSmeContext.auth_ft_ies);
pMac->ft.ftSmeContext.auth_ft_ies_length = 0;
}
-
+ ft_ies_length = VOS_MIN(ft_ies_length, MAX_FTIE_SIZE);
// Save the FT IEs
pMac->ft.ftSmeContext.auth_ft_ies = vos_mem_malloc(ft_ies_length);
if ( NULL == pMac->ft.ftSmeContext.auth_ft_ies )
@@ -138,9 +162,6 @@ void sme_SetFTIEs( tHalHandle hHal, tANI_U8 sessionId, const tANI_U8 *ft_ies,
ft_ies,ft_ies_length);
pMac->ft.ftSmeContext.FTState = eFT_AUTH_REQ_READY;
-#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
- smsLog( pMac, LOG1, "ft_ies_length=%d", ft_ies_length);
-#endif
break;
case eFT_AUTH_COMPLETE:
diff --git a/drivers/staging/prima/CORE/SVC/inc/wlan_btc_svc.h b/drivers/staging/prima/CORE/SVC/inc/wlan_btc_svc.h
index 104de94301c..a1f27be514a 100644
--- a/drivers/staging/prima/CORE/SVC/inc/wlan_btc_svc.h
+++ b/drivers/staging/prima/CORE/SVC/inc/wlan_btc_svc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -35,5 +35,6 @@
void send_btc_nlink_msg (int type, int dest_pid);
int btc_activate_service(void *pAdapter);
+void btc_deactivate_service(void);
#endif
diff --git a/drivers/staging/prima/CORE/SVC/src/btc/wlan_btc_svc.c b/drivers/staging/prima/CORE/SVC/src/btc/wlan_btc_svc.c
index bc38829c660..f64605d81f2 100644
--- a/drivers/staging/prima/CORE/SVC/src/btc/wlan_btc_svc.c
+++ b/drivers/staging/prima/CORE/SVC/src/btc/wlan_btc_svc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -213,6 +213,21 @@ int btc_activate_service(void *pAdapter)
nl_srv_register(WLAN_NL_MSG_BTC, btc_msg_callback);
return 0;
}
+
+/**---------------------------------------------------------------------------
+
+ \brief btc_deactivate_service() - Deactivate btc message handler
+
+ This function unregisters a handler to receive netlink messages
+ addressed to WLAN_NL_MSG_BTC from user space.
+
+ \return - none
+ --------------------------------------------------------------------------*/
+void btc_deactivate_service()
+{
+ //unregister the msg handler for msgs addressed to ANI_NL_MSG_BTC
+ nl_srv_unregister(WLAN_NL_MSG_BTC, btc_msg_callback);
+}
/*
* Callback function invoked by Netlink service for all netlink
* messages (from user space) addressed to WLAN_NL_MSG_BTC
diff --git a/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/dot11f.c b/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/dot11f.c
index ebdb096da29..a27f48aa954 100644
--- a/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/dot11f.c
+++ b/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/dot11f.c
@@ -28,7 +28,7 @@
*
*
* This file was automatically generated by 'framesc'
- * Tue Jul 4 11:19:48 2017 from the following file(s):
+ * Wed Jul 12 16:02:49 2017 from the following file(s):
*
* dot11f.frms
*
@@ -469,7 +469,7 @@ static tANI_U32 GetContainerIesLen(tpAniSirGlobal pCtx,
{
const tIEDefn *pIe, *pIeFirst;
tANI_U8 *pBufRemaining = pBuf;
- tANI_U8 len = 0;
+ tANI_U32 len = 0;
(void)pCtx;
@@ -5640,6 +5640,47 @@ tANI_U32 dot11fUnpackIeWscReassocRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8
#define SigIeWscReassocRes ( 0x008f )
+tANI_U32 dot11fUnpackIehs20vendor_ie(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEhs20vendor_ie *pDst)
+{
+ tANI_U32 status = DOT11F_PARSE_SUCCESS;
+ tANI_U8 tmp78__;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present) status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ tmp78__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->dgaf_dis = tmp78__ >> 0 & 0x1;
+ pDst->hs_id_present = tmp78__ >> 1 & 0x3;
+ pDst->reserved = tmp78__ >> 3 & 0x1;
+ pDst->release_num = tmp78__ >> 4 & 0xf;
+ if ( ! ielen )
+ {
+ return 0U;
+ }
+ else
+ {
+ switch (pDst->hs_id_present)
+ {
+ case 1:
+ framesntohs(pCtx, &pDst->hs_id.pps_mo.pps_mo_id, pBuf, 0);
+ pBuf += 2;
+ ielen -= (tANI_U8)2;
+ break;
+ case 2:
+ framesntohs(pCtx, &pDst->hs_id.anqp_domain.anqp_domain_id, pBuf, 0);
+ pBuf += 2;
+ ielen -= (tANI_U8)2;
+ break;
+ }
+ }
+ (void)pCtx;
+ return status;
+} /* End dot11fUnpackIehs20vendor_ie. */
+
+#define SigIehs20vendor_ie ( 0x0090 )
+
+
static const tFFDefn FFS_AddBAReq[] = {
{ "Category", offsetof(tDot11fAddBAReq, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, },
{ "Action", offsetof(tDot11fAddBAReq, Action), SigFfAction , DOT11F_FF_ACTION_LEN, },
@@ -6297,6 +6338,7 @@ tANI_U32 dot11fUnpackAddTSResponse(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32
{offsetof(tDot11fAssocRequest, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 3, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
{offsetof(tDot11fAssocRequest, OperatingMode), offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode" , 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OPERATINGMODE, 0, },
{offsetof(tDot11fAssocRequest, QosMapSet), offsetof(tDot11fIEQosMapSet, present), 0, "QosMapSet" , 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSMAPSET, 0, },
+ {offsetof(tDot11fAssocRequest, hs20vendor_ie), offsetof(tDot11fIEhs20vendor_ie, present), 0, "hs20vendor_ie" , 0, 7, 9, SigIehs20vendor_ie, {80, 111, 154, 16, 0}, 4, DOT11F_EID_HS20VENDOR_IE, 0, },
{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, };
tANI_U32 dot11fUnpackAssocRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fAssocRequest *pFrm)
@@ -6889,6 +6931,27 @@ tANI_U32 dot11fUnpackAssocRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 n
FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_dscp_exceptions: %d.\n"), pFrm->QosMapSet.num_dscp_exceptions);
FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->QosMapSet.dscp_exceptions, pFrm->QosMapSet.num_dscp_exceptions);
}
+ FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("hs20vendor_ie:\n"));
+ if (!pFrm->hs20vendor_ie.present)
+ {
+ FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n"));
+ }
+ else
+ {
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("dgaf_dis (1): %d\n"), pFrm->hs20vendor_ie.dgaf_dis);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("hs_id_present (2): %d\n"), pFrm->hs20vendor_ie.hs_id_present);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved (1): %d\n"), pFrm->hs20vendor_ie.reserved);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("release_num (4): %d\n"), pFrm->hs20vendor_ie.release_num);
+ switch (pFrm->hs20vendor_ie.hs_id_present)
+ {
+ case 1:
+ FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.pps_mo.pps_mo_id, 2);
+ break;
+ case 2:
+ FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.anqp_domain.anqp_domain_id, 2);
+ break;
+ }
+ }
}
# endif // DOT11F_DUMP_FRAMES
return status;
@@ -8501,6 +8564,7 @@ tANI_U32 dot11fUnpackAuthentication(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32
{offsetof(tDot11fBeacon, OperatingMode), offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode" , 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OPERATINGMODE, 0, },
{offsetof(tDot11fBeacon, WiderBWChanSwitchAnn), offsetof(tDot11fIEWiderBWChanSwitchAnn, present), 0, "WiderBWChanSwitchAnn" , 0, 5, 5, SigIeWiderBWChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WIDERBWCHANSWITCHANN, 0, },
{offsetof(tDot11fBeacon, OBSSScanParameters), offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters" , 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, },
+ {offsetof(tDot11fBeacon, hs20vendor_ie), offsetof(tDot11fIEhs20vendor_ie, present), 0, "hs20vendor_ie" , 0, 7, 9, SigIehs20vendor_ie, {80, 111, 154, 16, 0}, 4, DOT11F_EID_HS20VENDOR_IE, 0, },
{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, };
tANI_U32 dot11fUnpackBeacon(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fBeacon *pFrm)
@@ -9551,6 +9615,27 @@ tANI_U32 dot11fUnpackBeacon(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, t
FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2);
FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2);
}
+ FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("hs20vendor_ie:\n"));
+ if (!pFrm->hs20vendor_ie.present)
+ {
+ FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n"));
+ }
+ else
+ {
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("dgaf_dis (1): %d\n"), pFrm->hs20vendor_ie.dgaf_dis);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("hs_id_present (2): %d\n"), pFrm->hs20vendor_ie.hs_id_present);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (1): %d\n"), pFrm->hs20vendor_ie.reserved);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("release_num (4): %d\n"), pFrm->hs20vendor_ie.release_num);
+ switch (pFrm->hs20vendor_ie.hs_id_present)
+ {
+ case 1:
+ FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.pps_mo.pps_mo_id, 2);
+ break;
+ case 2:
+ FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.anqp_domain.anqp_domain_id, 2);
+ break;
+ }
+ }
}
# endif // DOT11F_DUMP_FRAMES
return status;
@@ -9687,6 +9772,7 @@ tANI_U32 dot11fUnpackBeacon1(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf,
{offsetof(tDot11fBeacon2, OperatingMode), offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode" , 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OPERATINGMODE, 0, },
{offsetof(tDot11fBeacon2, WiderBWChanSwitchAnn), offsetof(tDot11fIEWiderBWChanSwitchAnn, present), 0, "WiderBWChanSwitchAnn" , 0, 5, 5, SigIeWiderBWChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WIDERBWCHANSWITCHANN, 0, },
{offsetof(tDot11fBeacon2, OBSSScanParameters), offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters" , 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, },
+ {offsetof(tDot11fBeacon2, hs20vendor_ie), offsetof(tDot11fIEhs20vendor_ie, present), 0, "hs20vendor_ie" , 0, 7, 9, SigIehs20vendor_ie, {80, 111, 154, 16, 0}, 4, DOT11F_EID_HS20VENDOR_IE, 0, },
{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, };
tANI_U32 dot11fUnpackBeacon2(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fBeacon2 *pFrm)
@@ -10585,6 +10671,27 @@ tANI_U32 dot11fUnpackBeacon2(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf,
FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2);
FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2);
}
+ FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("hs20vendor_ie:\n"));
+ if (!pFrm->hs20vendor_ie.present)
+ {
+ FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n"));
+ }
+ else
+ {
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("dgaf_dis (1): %d\n"), pFrm->hs20vendor_ie.dgaf_dis);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("hs_id_present (2): %d\n"), pFrm->hs20vendor_ie.hs_id_present);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (1): %d\n"), pFrm->hs20vendor_ie.reserved);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("release_num (4): %d\n"), pFrm->hs20vendor_ie.release_num);
+ switch (pFrm->hs20vendor_ie.hs_id_present)
+ {
+ case 1:
+ FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.pps_mo.pps_mo_id, 2);
+ break;
+ case 2:
+ FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.anqp_domain.anqp_domain_id, 2);
+ break;
+ }
+ }
}
# endif // DOT11F_DUMP_FRAMES
return status;
@@ -10641,6 +10748,7 @@ tANI_U32 dot11fUnpackBeacon2(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf,
{offsetof(tDot11fBeaconIEs, OperatingMode), offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode" , 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OPERATINGMODE, 0, },
{offsetof(tDot11fBeaconIEs, WiderBWChanSwitchAnn), offsetof(tDot11fIEWiderBWChanSwitchAnn, present), 0, "WiderBWChanSwitchAnn" , 0, 5, 5, SigIeWiderBWChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WIDERBWCHANSWITCHANN, 0, },
{offsetof(tDot11fBeaconIEs, OBSSScanParameters), offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters" , 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, },
+ {offsetof(tDot11fBeaconIEs, hs20vendor_ie), offsetof(tDot11fIEhs20vendor_ie, present), 0, "hs20vendor_ie" , 0, 7, 9, SigIehs20vendor_ie, {80, 111, 154, 16, 0}, 4, DOT11F_EID_HS20VENDOR_IE, 0, },
{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, };
tANI_U32 dot11fUnpackBeaconIEs(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fBeaconIEs *pFrm)
@@ -11799,6 +11907,27 @@ tANI_U32 dot11fUnpackBeaconIEs(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf
FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2);
FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2);
}
+ FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("hs20vendor_ie:\n"));
+ if (!pFrm->hs20vendor_ie.present)
+ {
+ FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n"));
+ }
+ else
+ {
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("dgaf_dis (1): %d\n"), pFrm->hs20vendor_ie.dgaf_dis);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("hs_id_present (2): %d\n"), pFrm->hs20vendor_ie.hs_id_present);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (1): %d\n"), pFrm->hs20vendor_ie.reserved);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("release_num (4): %d\n"), pFrm->hs20vendor_ie.release_num);
+ switch (pFrm->hs20vendor_ie.hs_id_present)
+ {
+ case 1:
+ FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.pps_mo.pps_mo_id, 2);
+ break;
+ case 2:
+ FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.anqp_domain.anqp_domain_id, 2);
+ break;
+ }
+ }
}
# endif // DOT11F_DUMP_FRAMES
return status;
@@ -14132,6 +14261,7 @@ tANI_U32 dot11fUnpackProbeRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 n
{offsetof(tDot11fProbeResponse, VHTExtBssLoad), offsetof(tDot11fIEVHTExtBssLoad, present), 0, "VHTExtBssLoad" , 0, 7, 7, SigIeVHTExtBssLoad, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTEXTBSSLOAD, 0, },
{offsetof(tDot11fProbeResponse, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 3, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
{offsetof(tDot11fProbeResponse, OBSSScanParameters), offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters" , 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, },
+ {offsetof(tDot11fProbeResponse, hs20vendor_ie), offsetof(tDot11fIEhs20vendor_ie, present), 0, "hs20vendor_ie" , 0, 7, 9, SigIehs20vendor_ie, {80, 111, 154, 16, 0}, 4, DOT11F_EID_HS20VENDOR_IE, 0, },
{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, };
tANI_U32 dot11fUnpackProbeResponse(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fProbeResponse *pFrm)
@@ -15236,6 +15366,27 @@ tANI_U32 dot11fUnpackProbeResponse(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32
FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2);
FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2);
}
+ FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("hs20vendor_ie:\n"));
+ if (!pFrm->hs20vendor_ie.present)
+ {
+ FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n"));
+ }
+ else
+ {
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("dgaf_dis (1): %d\n"), pFrm->hs20vendor_ie.dgaf_dis);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("hs_id_present (2): %d\n"), pFrm->hs20vendor_ie.hs_id_present);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (1): %d\n"), pFrm->hs20vendor_ie.reserved);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("release_num (4): %d\n"), pFrm->hs20vendor_ie.release_num);
+ switch (pFrm->hs20vendor_ie.hs_id_present)
+ {
+ case 1:
+ FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.pps_mo.pps_mo_id, 2);
+ break;
+ case 2:
+ FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.anqp_domain.anqp_domain_id, 2);
+ break;
+ }
+ }
}
# endif // DOT11F_DUMP_FRAMES
return status;
@@ -15703,6 +15854,7 @@ tANI_U32 dot11fUnpackRadioMeasurementRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf,
{offsetof(tDot11fReAssocRequest, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 3, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
{offsetof(tDot11fReAssocRequest, OperatingMode), offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode" , 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OPERATINGMODE, 0, },
{offsetof(tDot11fReAssocRequest, QosMapSet), offsetof(tDot11fIEQosMapSet, present), 0, "QosMapSet" , 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSMAPSET, 0, },
+ {offsetof(tDot11fReAssocRequest, hs20vendor_ie), offsetof(tDot11fIEhs20vendor_ie, present), 0, "hs20vendor_ie" , 0, 7, 9, SigIehs20vendor_ie, {80, 111, 154, 16, 0}, 4, DOT11F_EID_HS20VENDOR_IE, 0, },
{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, };
tANI_U32 dot11fUnpackReAssocRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fReAssocRequest *pFrm)
@@ -16682,6 +16834,27 @@ tANI_U32 dot11fUnpackReAssocRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32
FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_dscp_exceptions: %d.\n"), pFrm->QosMapSet.num_dscp_exceptions);
FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->QosMapSet.dscp_exceptions, pFrm->QosMapSet.num_dscp_exceptions);
}
+ FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("hs20vendor_ie:\n"));
+ if (!pFrm->hs20vendor_ie.present)
+ {
+ FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n"));
+ }
+ else
+ {
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("dgaf_dis (1): %d\n"), pFrm->hs20vendor_ie.dgaf_dis);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("hs_id_present (2): %d\n"), pFrm->hs20vendor_ie.hs_id_present);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (1): %d\n"), pFrm->hs20vendor_ie.reserved);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("release_num (4): %d\n"), pFrm->hs20vendor_ie.release_num);
+ switch (pFrm->hs20vendor_ie.hs_id_present)
+ {
+ case 1:
+ FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.pps_mo.pps_mo_id, 2);
+ break;
+ case 2:
+ FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.anqp_domain.anqp_domain_id, 2);
+ break;
+ }
+ }
}
# endif // DOT11F_DUMP_FRAMES
return status;
@@ -20714,6 +20887,9 @@ static tANI_U32 UnpackCore(tpAniSirGlobal pCtx,
case SigIeWscReassocRes:
status |= dot11fUnpackIeWscReassocRes(pCtx, pBufRemaining, len, ( tDot11fIEWscReassocRes* )(pFrm + pIe->offset + sizeof(tDot11fIEWscReassocRes)*countOffset) );
break;
+ case SigIehs20vendor_ie:
+ status |= dot11fUnpackIehs20vendor_ie(pCtx, pBufRemaining, len, ( tDot11fIEhs20vendor_ie* )(pFrm + pIe->offset + sizeof(tDot11fIEhs20vendor_ie)*countOffset) );
+ break;
default:
FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR"
": I don't know about the IE signature %d"
@@ -21840,6 +22016,31 @@ tANI_U32 dot11fGetPackedIEWscReassocRes(tpAniSirGlobal pCtx, tDot11fIEWscReassoc
return status;
} /* End dot11fGetPackedIEWscReassocRes. */
+tANI_U32 dot11fGetPackedIEhs20vendor_ie(tpAniSirGlobal pCtx, tDot11fIEhs20vendor_ie *pIe, tANI_U32 *pnNeeded)
+{
+ tANI_U32 status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while ( pIe->present )
+ {
+ *pnNeeded += 1;
+ if ( pIe->hs_id_present )
+ {
+ switch (pIe->hs_id_present)
+ {
+ case 1:
+ *pnNeeded += 2;
+ break;
+ case 2:
+ *pnNeeded += 2;
+ break;
+ }
+ }
+ else break;
+ break;
+ }
+ return status;
+} /* End dot11fGetPackedIEhs20vendor_ie. */
+
tANI_U32 dot11fGetPackedAddBAReqSize(tpAniSirGlobal pCtx, tDot11fAddBAReq *pFrm, tANI_U32 *pnNeeded)
{
tANI_U32 status = 0;
@@ -23044,6 +23245,10 @@ static tANI_U32 GetPackedSizeCore(tpAniSirGlobal pCtx,
offset = sizeof(tDot11fIEWscReassocRes);
status |= dot11fGetPackedIEWscReassocRes(pCtx, ( tDot11fIEWscReassocRes* )(pFrm + pIe->offset + offset * i ), pnNeeded);
break;
+ case SigIehs20vendor_ie:
+ offset = sizeof(tDot11fIEhs20vendor_ie);
+ status |= dot11fGetPackedIEhs20vendor_ie(pCtx, ( tDot11fIEhs20vendor_ie* )(pFrm + pIe->offset + offset * i ), pnNeeded);
+ break;
default:
FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR-- I don"
"'t know about the IE signature %d; this is most l"
@@ -23296,13 +23501,13 @@ void dot11fPackFfAddBAParameterSet(tpAniSirGlobal pCtx,
tDot11fFfAddBAParameterSet *pSrc,
tANI_U8 *pBuf)
{
- tANI_U16 tmp78__;
- tmp78__ = 0U;
- tmp78__ |= ( pSrc->amsduSupported << 0 );
- tmp78__ |= ( pSrc->policy << 1 );
- tmp78__ |= ( pSrc->tid << 2 );
- tmp78__ |= ( pSrc->bufferSize << 6 );
- frameshtons(pCtx, pBuf, tmp78__, 0);
+ tANI_U16 tmp79__;
+ tmp79__ = 0U;
+ tmp79__ |= ( pSrc->amsduSupported << 0 );
+ tmp79__ |= ( pSrc->policy << 1 );
+ tmp79__ |= ( pSrc->tid << 2 );
+ tmp79__ |= ( pSrc->bufferSize << 6 );
+ frameshtons(pCtx, pBuf, tmp79__, 0);
(void)pCtx;
} /* End dot11fPackFfAddBAParameterSet. */
@@ -23326,11 +23531,11 @@ void dot11fPackFfBAStartingSequenceControl(tpAniSirGlobal pCtx,
tDot11fFfBAStartingSequenceControl *pSrc,
tANI_U8 *pBuf)
{
- tANI_U16 tmp79__;
- tmp79__ = 0U;
- tmp79__ |= ( pSrc->fragNumber << 0 );
- tmp79__ |= ( pSrc->ssn << 4 );
- frameshtons(pCtx, pBuf, tmp79__, 0);
+ tANI_U16 tmp80__;
+ tmp80__ = 0U;
+ tmp80__ |= ( pSrc->fragNumber << 0 );
+ tmp80__ |= ( pSrc->ssn << 4 );
+ frameshtons(pCtx, pBuf, tmp80__, 0);
(void)pCtx;
} /* End dot11fPackFfBAStartingSequenceControl. */
@@ -23354,25 +23559,25 @@ void dot11fPackFfCapabilities(tpAniSirGlobal pCtx,
tDot11fFfCapabilities *pSrc,
tANI_U8 *pBuf)
{
- tANI_U16 tmp80__;
- tmp80__ = 0U;
- tmp80__ |= ( pSrc->ess << 0 );
- tmp80__ |= ( pSrc->ibss << 1 );
- tmp80__ |= ( pSrc->cfPollable << 2 );
- tmp80__ |= ( pSrc->cfPollReq << 3 );
- tmp80__ |= ( pSrc->privacy << 4 );
- tmp80__ |= ( pSrc->shortPreamble << 5 );
- tmp80__ |= ( pSrc->pbcc << 6 );
- tmp80__ |= ( pSrc->channelAgility << 7 );
- tmp80__ |= ( pSrc->spectrumMgt << 8 );
- tmp80__ |= ( pSrc->qos << 9 );
- tmp80__ |= ( pSrc->shortSlotTime << 10 );
- tmp80__ |= ( pSrc->apsd << 11 );
- tmp80__ |= ( pSrc->rrm << 12 );
- tmp80__ |= ( pSrc->dsssOfdm << 13 );
- tmp80__ |= ( pSrc->delayedBA << 14 );
- tmp80__ |= ( pSrc->immediateBA << 15 );
- frameshtons(pCtx, pBuf, tmp80__, 0);
+ tANI_U16 tmp81__;
+ tmp81__ = 0U;
+ tmp81__ |= ( pSrc->ess << 0 );
+ tmp81__ |= ( pSrc->ibss << 1 );
+ tmp81__ |= ( pSrc->cfPollable << 2 );
+ tmp81__ |= ( pSrc->cfPollReq << 3 );
+ tmp81__ |= ( pSrc->privacy << 4 );
+ tmp81__ |= ( pSrc->shortPreamble << 5 );
+ tmp81__ |= ( pSrc->pbcc << 6 );
+ tmp81__ |= ( pSrc->channelAgility << 7 );
+ tmp81__ |= ( pSrc->spectrumMgt << 8 );
+ tmp81__ |= ( pSrc->qos << 9 );
+ tmp81__ |= ( pSrc->shortSlotTime << 10 );
+ tmp81__ |= ( pSrc->apsd << 11 );
+ tmp81__ |= ( pSrc->rrm << 12 );
+ tmp81__ |= ( pSrc->dsssOfdm << 13 );
+ tmp81__ |= ( pSrc->delayedBA << 14 );
+ tmp81__ |= ( pSrc->immediateBA << 15 );
+ frameshtons(pCtx, pBuf, tmp81__, 0);
(void)pCtx;
} /* End dot11fPackFfCapabilities. */
@@ -23396,12 +23601,12 @@ void dot11fPackFfDelBAParameterSet(tpAniSirGlobal pCtx,
tDot11fFfDelBAParameterSet *pSrc,
tANI_U8 *pBuf)
{
- tANI_U16 tmp81__;
- tmp81__ = 0U;
- tmp81__ |= ( pSrc->reserved << 0 );
- tmp81__ |= ( pSrc->initiator << 11 );
- tmp81__ |= ( pSrc->tid << 12 );
- frameshtons(pCtx, pBuf, tmp81__, 0);
+ tANI_U16 tmp82__;
+ tmp82__ = 0U;
+ tmp82__ |= ( pSrc->reserved << 0 );
+ tmp82__ |= ( pSrc->initiator << 11 );
+ tmp82__ |= ( pSrc->tid << 12 );
+ frameshtons(pCtx, pBuf, tmp82__, 0);
(void)pCtx;
} /* End dot11fPackFfDelBAParameterSet. */
@@ -23457,13 +23662,13 @@ void dot11fPackFfOperatingMode(tpAniSirGlobal pCtx,
tDot11fFfOperatingMode *pSrc,
tANI_U8 *pBuf)
{
- tANI_U8 tmp82__;
- tmp82__ = 0U;
- tmp82__ |= ( pSrc->chanWidth << 0 );
- tmp82__ |= ( pSrc->reserved << 2 );
- tmp82__ |= ( pSrc->rxNSS << 4 );
- tmp82__ |= ( pSrc->rxNSSType << 7 );
- *pBuf = tmp82__;
+ tANI_U8 tmp83__;
+ tmp83__ = 0U;
+ tmp83__ |= ( pSrc->chanWidth << 0 );
+ tmp83__ |= ( pSrc->reserved << 2 );
+ tmp83__ |= ( pSrc->rxNSS << 4 );
+ tmp83__ |= ( pSrc->rxNSSType << 7 );
+ *pBuf = tmp83__;
(void)pCtx;
} /* End dot11fPackFfOperatingMode. */
@@ -23551,12 +23756,12 @@ void dot11fPackFfSMPowerModeSet(tpAniSirGlobal pCtx,
tDot11fFfSMPowerModeSet *pSrc,
tANI_U8 *pBuf)
{
- tANI_U8 tmp83__;
- tmp83__ = 0U;
- tmp83__ |= ( pSrc->PowerSave_En << 0 );
- tmp83__ |= ( pSrc->Mode << 1 );
- tmp83__ |= ( pSrc->reserved << 2 );
- *pBuf = tmp83__;
+ tANI_U8 tmp84__;
+ tmp84__ = 0U;
+ tmp84__ |= ( pSrc->PowerSave_En << 0 );
+ tmp84__ |= ( pSrc->Mode << 1 );
+ tmp84__ |= ( pSrc->reserved << 2 );
+ *pBuf = tmp84__;
(void)pCtx;
} /* End dot11fPackFfSMPowerModeSet. */
@@ -23596,19 +23801,19 @@ void dot11fPackFfTSInfo(tpAniSirGlobal pCtx,
tDot11fFfTSInfo *pSrc,
tANI_U8 *pBuf)
{
- tANI_U32 tmp84__;
- tmp84__ = 0U;
- tmp84__ |= ( pSrc->traffic_type << 0 );
- tmp84__ |= ( pSrc->tsid << 1 );
- tmp84__ |= ( pSrc->direction << 5 );
- tmp84__ |= ( pSrc->access_policy << 7 );
- tmp84__ |= ( pSrc->aggregation << 9 );
- tmp84__ |= ( pSrc->psb << 10 );
- tmp84__ |= ( pSrc->user_priority << 11 );
- tmp84__ |= ( pSrc->tsinfo_ack_pol << 14 );
- tmp84__ |= ( pSrc->schedule << 16 );
- tmp84__ |= ( pSrc->unused << 17 );
- frameshtonl(pCtx, pBuf, tmp84__, 0);
+ tANI_U32 tmp85__;
+ tmp85__ = 0U;
+ tmp85__ |= ( pSrc->traffic_type << 0 );
+ tmp85__ |= ( pSrc->tsid << 1 );
+ tmp85__ |= ( pSrc->direction << 5 );
+ tmp85__ |= ( pSrc->access_policy << 7 );
+ tmp85__ |= ( pSrc->aggregation << 9 );
+ tmp85__ |= ( pSrc->psb << 10 );
+ tmp85__ |= ( pSrc->user_priority << 11 );
+ tmp85__ |= ( pSrc->tsinfo_ack_pol << 14 );
+ tmp85__ |= ( pSrc->schedule << 16 );
+ tmp85__ |= ( pSrc->unused << 17 );
+ frameshtonl(pCtx, pBuf, tmp85__, 0);
(void)pCtx;
} /* End dot11fPackFfTSInfo. */
@@ -23729,7 +23934,7 @@ tANI_U32 dot11fPackTlvVersion2(tpAniSirGlobal pCtx,
tANI_U8* pTlvLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U8 tmp85__;
+ tANI_U8 tmp86__;
nNeeded += 3;
if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW;
while ( pSrc->present )
@@ -23738,10 +23943,10 @@ tANI_U32 dot11fPackTlvVersion2(tpAniSirGlobal pCtx,
pBuf += 1; *pnConsumed += 1;
pTlvLen = pBuf;
pBuf += 1; *pnConsumed += 1;
- tmp85__ = 0U;
- tmp85__ |= ( pSrc->minor << 0 );
- tmp85__ |= ( pSrc->major << 4 );
- *pBuf = tmp85__;
+ tmp86__ = 0U;
+ tmp86__ |= ( pSrc->minor << 0 );
+ tmp86__ |= ( pSrc->major << 4 );
+ *pBuf = tmp86__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
@@ -24950,7 +25155,7 @@ tANI_U32 dot11fPackTlvVersion(tpAniSirGlobal pCtx,
tANI_U8* pTlvLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U8 tmp86__;
+ tANI_U8 tmp87__;
nNeeded += 5;
if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW;
while ( pSrc->present )
@@ -24959,10 +25164,10 @@ tANI_U32 dot11fPackTlvVersion(tpAniSirGlobal pCtx,
pBuf += 2; *pnConsumed += 2;
pTlvLen = pBuf;
pBuf += 2; *pnConsumed += 2;
- tmp86__ = 0U;
- tmp86__ |= ( pSrc->minor << 0 );
- tmp86__ |= ( pSrc->major << 4 );
- *pBuf = tmp86__;
+ tmp87__ = 0U;
+ tmp87__ |= ( pSrc->minor << 0 );
+ tmp87__ |= ( pSrc->major << 4 );
+ *pBuf = tmp87__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
@@ -25168,7 +25373,7 @@ tANI_U32 dot11fPackIeGTK(tpAniSirGlobal pCtx,
tANI_U8* pIeLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U16 tmp87__;
+ tANI_U16 tmp88__;
nNeeded += (pSrc->num_key + 11);
while ( pSrc->present )
{
@@ -25177,10 +25382,10 @@ tANI_U32 dot11fPackIeGTK(tpAniSirGlobal pCtx,
++pBuf; ++(*pnConsumed);
pIeLen = pBuf;
++pBuf; ++(*pnConsumed);
- tmp87__ = 0U;
- tmp87__ |= ( pSrc->keyId << 0 );
- tmp87__ |= ( pSrc->reserved << 2 );
- frameshtons(pCtx, pBuf, tmp87__, 0);
+ tmp88__ = 0U;
+ tmp88__ |= ( pSrc->keyId << 0 );
+ tmp88__ |= ( pSrc->reserved << 2 );
+ frameshtons(pCtx, pBuf, tmp88__, 0);
*pnConsumed += 2;
pBuf += 2;
nBuf -= 2 ;
@@ -25476,7 +25681,6 @@ tANI_U32 dot11fPackIePropEDCAParams(tpAniSirGlobal pCtx,
tANI_U8* pIeLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U8 tmp88__;
tANI_U8 tmp89__;
tANI_U8 tmp90__;
tANI_U8 tmp91__;
@@ -25484,6 +25688,7 @@ tANI_U32 dot11fPackIePropEDCAParams(tpAniSirGlobal pCtx,
tANI_U8 tmp93__;
tANI_U8 tmp94__;
tANI_U8 tmp95__;
+ tANI_U8 tmp96__;
nNeeded += 18;
while ( pSrc->present )
{
@@ -25498,79 +25703,79 @@ tANI_U32 dot11fPackIePropEDCAParams(tpAniSirGlobal pCtx,
*pBuf = pSrc->reserved;
*pnConsumed += 1;
pBuf += 1;
- tmp88__ = 0U;
- tmp88__ |= ( pSrc->acbe_aifsn << 0 );
- tmp88__ |= ( pSrc->acbe_acm << 4 );
- tmp88__ |= ( pSrc->acbe_aci << 5 );
- tmp88__ |= ( pSrc->unused1 << 7 );
- *pBuf = tmp88__;
- *pnConsumed += 1;
- pBuf += 1;
- nBuf -= 1 ;
tmp89__ = 0U;
- tmp89__ |= ( pSrc->acbe_min << 0 );
- tmp89__ |= ( pSrc->acbe_max << 4 );
+ tmp89__ |= ( pSrc->acbe_aifsn << 0 );
+ tmp89__ |= ( pSrc->acbe_acm << 4 );
+ tmp89__ |= ( pSrc->acbe_aci << 5 );
+ tmp89__ |= ( pSrc->unused1 << 7 );
*pBuf = tmp89__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
- frameshtons(pCtx, pBuf, pSrc->acbe_txoplimit, 0);
- *pnConsumed += 2;
- pBuf += 2;
tmp90__ = 0U;
- tmp90__ |= ( pSrc->acbk_aifsn << 0 );
- tmp90__ |= ( pSrc->acbk_acm << 4 );
- tmp90__ |= ( pSrc->acbk_aci << 5 );
- tmp90__ |= ( pSrc->unused2 << 7 );
+ tmp90__ |= ( pSrc->acbe_min << 0 );
+ tmp90__ |= ( pSrc->acbe_max << 4 );
*pBuf = tmp90__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
+ frameshtons(pCtx, pBuf, pSrc->acbe_txoplimit, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
tmp91__ = 0U;
- tmp91__ |= ( pSrc->acbk_min << 0 );
- tmp91__ |= ( pSrc->acbk_max << 4 );
+ tmp91__ |= ( pSrc->acbk_aifsn << 0 );
+ tmp91__ |= ( pSrc->acbk_acm << 4 );
+ tmp91__ |= ( pSrc->acbk_aci << 5 );
+ tmp91__ |= ( pSrc->unused2 << 7 );
*pBuf = tmp91__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
- frameshtons(pCtx, pBuf, pSrc->acbk_txoplimit, 0);
- *pnConsumed += 2;
- pBuf += 2;
tmp92__ = 0U;
- tmp92__ |= ( pSrc->acvi_aifsn << 0 );
- tmp92__ |= ( pSrc->acvi_acm << 4 );
- tmp92__ |= ( pSrc->acvi_aci << 5 );
- tmp92__ |= ( pSrc->unused3 << 7 );
+ tmp92__ |= ( pSrc->acbk_min << 0 );
+ tmp92__ |= ( pSrc->acbk_max << 4 );
*pBuf = tmp92__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
+ frameshtons(pCtx, pBuf, pSrc->acbk_txoplimit, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
tmp93__ = 0U;
- tmp93__ |= ( pSrc->acvi_min << 0 );
- tmp93__ |= ( pSrc->acvi_max << 4 );
+ tmp93__ |= ( pSrc->acvi_aifsn << 0 );
+ tmp93__ |= ( pSrc->acvi_acm << 4 );
+ tmp93__ |= ( pSrc->acvi_aci << 5 );
+ tmp93__ |= ( pSrc->unused3 << 7 );
*pBuf = tmp93__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
- frameshtons(pCtx, pBuf, pSrc->acvi_txoplimit, 0);
- *pnConsumed += 2;
- pBuf += 2;
tmp94__ = 0U;
- tmp94__ |= ( pSrc->acvo_aifsn << 0 );
- tmp94__ |= ( pSrc->acvo_acm << 4 );
- tmp94__ |= ( pSrc->acvo_aci << 5 );
- tmp94__ |= ( pSrc->unused4 << 7 );
+ tmp94__ |= ( pSrc->acvi_min << 0 );
+ tmp94__ |= ( pSrc->acvi_max << 4 );
*pBuf = tmp94__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
+ frameshtons(pCtx, pBuf, pSrc->acvi_txoplimit, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
tmp95__ = 0U;
- tmp95__ |= ( pSrc->acvo_min << 0 );
- tmp95__ |= ( pSrc->acvo_max << 4 );
+ tmp95__ |= ( pSrc->acvo_aifsn << 0 );
+ tmp95__ |= ( pSrc->acvo_acm << 4 );
+ tmp95__ |= ( pSrc->acvo_aci << 5 );
+ tmp95__ |= ( pSrc->unused4 << 7 );
*pBuf = tmp95__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
+ tmp96__ = 0U;
+ tmp96__ |= ( pSrc->acvo_min << 0 );
+ tmp96__ |= ( pSrc->acvo_max << 4 );
+ *pBuf = tmp96__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
frameshtons(pCtx, pBuf, pSrc->acvo_txoplimit, 0);
*pnConsumed += 2;
// fieldsEndFlag = 1
@@ -25755,7 +25960,7 @@ tANI_U32 dot11fPackIeTaurus(tpAniSirGlobal pCtx,
tANI_U8* pIeLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U16 tmp96__;
+ tANI_U16 tmp97__;
nNeeded += 6;
while ( pSrc->present )
{
@@ -25770,10 +25975,10 @@ tANI_U32 dot11fPackIeTaurus(tpAniSirGlobal pCtx,
frameshtons(pCtx, pBuf, pSrc->baPolicy, 0);
*pnConsumed += 2;
pBuf += 2;
- tmp96__ = 0U;
- tmp96__ |= ( pSrc->baBufferSize << 0 );
- tmp96__ |= ( pSrc->rsvd << 12 );
- frameshtons(pCtx, pBuf, tmp96__, 0);
+ tmp97__ = 0U;
+ tmp97__ |= ( pSrc->baBufferSize << 0 );
+ tmp97__ |= ( pSrc->rsvd << 12 );
+ frameshtons(pCtx, pBuf, tmp97__, 0);
*pnConsumed += 2;
// fieldsEndFlag = 1
nBuf -= 2 ;
@@ -26192,11 +26397,11 @@ tANI_U32 dot11fPackIeRRMEnabledCap(tpAniSirGlobal pCtx,
tANI_U8* pIeLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U8 tmp97__;
tANI_U8 tmp98__;
tANI_U8 tmp99__;
tANI_U8 tmp100__;
tANI_U8 tmp101__;
+ tANI_U8 tmp102__;
nNeeded += 5;
while ( pSrc->present )
{
@@ -26205,58 +26410,58 @@ tANI_U32 dot11fPackIeRRMEnabledCap(tpAniSirGlobal pCtx,
++pBuf; ++(*pnConsumed);
pIeLen = pBuf;
++pBuf; ++(*pnConsumed);
- tmp97__ = 0U;
- tmp97__ |= ( pSrc->LinkMeasurement << 0 );
- tmp97__ |= ( pSrc->NeighborRpt << 1 );
- tmp97__ |= ( pSrc->parallel << 2 );
- tmp97__ |= ( pSrc->repeated << 3 );
- tmp97__ |= ( pSrc->BeaconPassive << 4 );
- tmp97__ |= ( pSrc->BeaconActive << 5 );
- tmp97__ |= ( pSrc->BeaconTable << 6 );
- tmp97__ |= ( pSrc->BeaconRepCond << 7 );
- *pBuf = tmp97__;
- *pnConsumed += 1;
- pBuf += 1;
- nBuf -= 1 ;
tmp98__ = 0U;
- tmp98__ |= ( pSrc->FrameMeasurement << 0 );
- tmp98__ |= ( pSrc->ChannelLoad << 1 );
- tmp98__ |= ( pSrc->NoiseHistogram << 2 );
- tmp98__ |= ( pSrc->statistics << 3 );
- tmp98__ |= ( pSrc->LCIMeasurement << 4 );
- tmp98__ |= ( pSrc->LCIAzimuth << 5 );
- tmp98__ |= ( pSrc->TCMCapability << 6 );
- tmp98__ |= ( pSrc->triggeredTCM << 7 );
+ tmp98__ |= ( pSrc->LinkMeasurement << 0 );
+ tmp98__ |= ( pSrc->NeighborRpt << 1 );
+ tmp98__ |= ( pSrc->parallel << 2 );
+ tmp98__ |= ( pSrc->repeated << 3 );
+ tmp98__ |= ( pSrc->BeaconPassive << 4 );
+ tmp98__ |= ( pSrc->BeaconActive << 5 );
+ tmp98__ |= ( pSrc->BeaconTable << 6 );
+ tmp98__ |= ( pSrc->BeaconRepCond << 7 );
*pBuf = tmp98__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
tmp99__ = 0U;
- tmp99__ |= ( pSrc->APChanReport << 0 );
- tmp99__ |= ( pSrc->RRMMIBEnabled << 1 );
- tmp99__ |= ( pSrc->operatingChanMax << 2 );
- tmp99__ |= ( pSrc->nonOperatinChanMax << 5 );
+ tmp99__ |= ( pSrc->FrameMeasurement << 0 );
+ tmp99__ |= ( pSrc->ChannelLoad << 1 );
+ tmp99__ |= ( pSrc->NoiseHistogram << 2 );
+ tmp99__ |= ( pSrc->statistics << 3 );
+ tmp99__ |= ( pSrc->LCIMeasurement << 4 );
+ tmp99__ |= ( pSrc->LCIAzimuth << 5 );
+ tmp99__ |= ( pSrc->TCMCapability << 6 );
+ tmp99__ |= ( pSrc->triggeredTCM << 7 );
*pBuf = tmp99__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
tmp100__ = 0U;
- tmp100__ |= ( pSrc->MeasurementPilot << 0 );
- tmp100__ |= ( pSrc->MeasurementPilotEnabled << 3 );
- tmp100__ |= ( pSrc->NeighborTSFOffset << 4 );
- tmp100__ |= ( pSrc->RCPIMeasurement << 5 );
- tmp100__ |= ( pSrc->RSNIMeasurement << 6 );
- tmp100__ |= ( pSrc->BssAvgAccessDelay << 7 );
+ tmp100__ |= ( pSrc->APChanReport << 0 );
+ tmp100__ |= ( pSrc->RRMMIBEnabled << 1 );
+ tmp100__ |= ( pSrc->operatingChanMax << 2 );
+ tmp100__ |= ( pSrc->nonOperatinChanMax << 5 );
*pBuf = tmp100__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
tmp101__ = 0U;
- tmp101__ |= ( pSrc->BSSAvailAdmission << 0 );
- tmp101__ |= ( pSrc->AntennaInformation << 1 );
- tmp101__ |= ( pSrc->reserved << 2 );
+ tmp101__ |= ( pSrc->MeasurementPilot << 0 );
+ tmp101__ |= ( pSrc->MeasurementPilotEnabled << 3 );
+ tmp101__ |= ( pSrc->NeighborTSFOffset << 4 );
+ tmp101__ |= ( pSrc->RCPIMeasurement << 5 );
+ tmp101__ |= ( pSrc->RSNIMeasurement << 6 );
+ tmp101__ |= ( pSrc->BssAvgAccessDelay << 7 );
*pBuf = tmp101__;
*pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ tmp102__ = 0U;
+ tmp102__ |= ( pSrc->BSSAvailAdmission << 0 );
+ tmp102__ |= ( pSrc->AntennaInformation << 1 );
+ tmp102__ |= ( pSrc->reserved << 2 );
+ *pBuf = tmp102__;
+ *pnConsumed += 1;
// fieldsEndFlag = 1
nBuf -= 1 ;
break;
@@ -26338,7 +26543,7 @@ tANI_U32 dot11fPackIeSchedule(tpAniSirGlobal pCtx,
tANI_U8* pIeLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U16 tmp102__;
+ tANI_U16 tmp103__;
nNeeded += 14;
while ( pSrc->present )
{
@@ -26347,12 +26552,12 @@ tANI_U32 dot11fPackIeSchedule(tpAniSirGlobal pCtx,
++pBuf; ++(*pnConsumed);
pIeLen = pBuf;
++pBuf; ++(*pnConsumed);
- tmp102__ = 0U;
- tmp102__ |= ( pSrc->aggregation << 0 );
- tmp102__ |= ( pSrc->tsid << 1 );
- tmp102__ |= ( pSrc->direction << 5 );
- tmp102__ |= ( pSrc->reserved << 7 );
- frameshtons(pCtx, pBuf, tmp102__, 0);
+ tmp103__ = 0U;
+ tmp103__ |= ( pSrc->aggregation << 0 );
+ tmp103__ |= ( pSrc->tsid << 1 );
+ tmp103__ |= ( pSrc->direction << 5 );
+ tmp103__ |= ( pSrc->reserved << 7 );
+ frameshtons(pCtx, pBuf, tmp103__, 0);
*pnConsumed += 2;
pBuf += 2;
nBuf -= 2 ;
@@ -26552,9 +26757,9 @@ tANI_U32 dot11fPackIeTSPEC(tpAniSirGlobal pCtx,
tANI_U8* pIeLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U16 tmp103__;
- tANI_U8 tmp104__;
- tANI_U16 tmp105__;
+ tANI_U16 tmp104__;
+ tANI_U8 tmp105__;
+ tANI_U16 tmp106__;
nNeeded += 55;
while ( pSrc->present )
{
@@ -26563,30 +26768,30 @@ tANI_U32 dot11fPackIeTSPEC(tpAniSirGlobal pCtx,
++pBuf; ++(*pnConsumed);
pIeLen = pBuf;
++pBuf; ++(*pnConsumed);
- tmp103__ = 0U;
- tmp103__ |= ( pSrc->traffic_type << 0 );
- tmp103__ |= ( pSrc->tsid << 1 );
- tmp103__ |= ( pSrc->direction << 5 );
- tmp103__ |= ( pSrc->access_policy << 7 );
- tmp103__ |= ( pSrc->aggregation << 9 );
- tmp103__ |= ( pSrc->psb << 10 );
- tmp103__ |= ( pSrc->user_priority << 11 );
- tmp103__ |= ( pSrc->tsinfo_ack_pol << 14 );
- frameshtons(pCtx, pBuf, tmp103__, 0);
+ tmp104__ = 0U;
+ tmp104__ |= ( pSrc->traffic_type << 0 );
+ tmp104__ |= ( pSrc->tsid << 1 );
+ tmp104__ |= ( pSrc->direction << 5 );
+ tmp104__ |= ( pSrc->access_policy << 7 );
+ tmp104__ |= ( pSrc->aggregation << 9 );
+ tmp104__ |= ( pSrc->psb << 10 );
+ tmp104__ |= ( pSrc->user_priority << 11 );
+ tmp104__ |= ( pSrc->tsinfo_ack_pol << 14 );
+ frameshtons(pCtx, pBuf, tmp104__, 0);
*pnConsumed += 2;
pBuf += 2;
nBuf -= 2 ;
- tmp104__ = 0U;
- tmp104__ |= ( pSrc->schedule << 0 );
- tmp104__ |= ( pSrc->unused << 1 );
- *pBuf = tmp104__;
+ tmp105__ = 0U;
+ tmp105__ |= ( pSrc->schedule << 0 );
+ tmp105__ |= ( pSrc->unused << 1 );
+ *pBuf = tmp105__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
- tmp105__ = 0U;
- tmp105__ |= ( pSrc->size << 0 );
- tmp105__ |= ( pSrc->fixed << 15 );
- frameshtons(pCtx, pBuf, tmp105__, 0);
+ tmp106__ = 0U;
+ tmp106__ |= ( pSrc->size << 0 );
+ tmp106__ |= ( pSrc->fixed << 15 );
+ frameshtons(pCtx, pBuf, tmp106__, 0);
*pnConsumed += 2;
pBuf += 2;
nBuf -= 2 ;
@@ -26651,7 +26856,7 @@ tANI_U32 dot11fPackIeWMMSchedule(tpAniSirGlobal pCtx,
tANI_U8* pIeLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U16 tmp106__;
+ tANI_U16 tmp107__;
nNeeded += 15;
while ( pSrc->present )
{
@@ -26673,12 +26878,12 @@ tANI_U32 dot11fPackIeWMMSchedule(tpAniSirGlobal pCtx,
*pBuf = pSrc->version;
*pnConsumed += 1;
pBuf += 1;
- tmp106__ = 0U;
- tmp106__ |= ( pSrc->aggregation << 0 );
- tmp106__ |= ( pSrc->tsid << 1 );
- tmp106__ |= ( pSrc->direction << 5 );
- tmp106__ |= ( pSrc->reserved << 7 );
- frameshtons(pCtx, pBuf, tmp106__, 0);
+ tmp107__ = 0U;
+ tmp107__ |= ( pSrc->aggregation << 0 );
+ tmp107__ |= ( pSrc->tsid << 1 );
+ tmp107__ |= ( pSrc->direction << 5 );
+ tmp107__ |= ( pSrc->reserved << 7 );
+ frameshtons(pCtx, pBuf, tmp107__, 0);
*pnConsumed += 2;
pBuf += 2;
nBuf -= 2 ;
@@ -26917,9 +27122,9 @@ tANI_U32 dot11fPackIeWMMTSPEC(tpAniSirGlobal pCtx,
tANI_U8* pIeLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U16 tmp107__;
- tANI_U8 tmp108__;
- tANI_U16 tmp109__;
+ tANI_U16 tmp108__;
+ tANI_U8 tmp109__;
+ tANI_U16 tmp110__;
nNeeded += 38;
while ( pSrc->present )
{
@@ -26941,30 +27146,30 @@ tANI_U32 dot11fPackIeWMMTSPEC(tpAniSirGlobal pCtx,
*pBuf = pSrc->version;
*pnConsumed += 1;
pBuf += 1;
- tmp107__ = 0U;
- tmp107__ |= ( pSrc->traffic_type << 0 );
- tmp107__ |= ( pSrc->tsid << 1 );
- tmp107__ |= ( pSrc->direction << 5 );
- tmp107__ |= ( pSrc->access_policy << 7 );
- tmp107__ |= ( pSrc->aggregation << 9 );
- tmp107__ |= ( pSrc->psb << 10 );
- tmp107__ |= ( pSrc->user_priority << 11 );
- tmp107__ |= ( pSrc->tsinfo_ack_pol << 14 );
- frameshtons(pCtx, pBuf, tmp107__, 0);
+ tmp108__ = 0U;
+ tmp108__ |= ( pSrc->traffic_type << 0 );
+ tmp108__ |= ( pSrc->tsid << 1 );
+ tmp108__ |= ( pSrc->direction << 5 );
+ tmp108__ |= ( pSrc->access_policy << 7 );
+ tmp108__ |= ( pSrc->aggregation << 9 );
+ tmp108__ |= ( pSrc->psb << 10 );
+ tmp108__ |= ( pSrc->user_priority << 11 );
+ tmp108__ |= ( pSrc->tsinfo_ack_pol << 14 );
+ frameshtons(pCtx, pBuf, tmp108__, 0);
*pnConsumed += 2;
pBuf += 2;
nBuf -= 2 ;
- tmp108__ = 0U;
- tmp108__ |= ( pSrc->tsinfo_rsvd << 0 );
- tmp108__ |= ( pSrc->burst_size_defn << 7 );
- *pBuf = tmp108__;
+ tmp109__ = 0U;
+ tmp109__ |= ( pSrc->tsinfo_rsvd << 0 );
+ tmp109__ |= ( pSrc->burst_size_defn << 7 );
+ *pBuf = tmp109__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
- tmp109__ = 0U;
- tmp109__ |= ( pSrc->size << 0 );
- tmp109__ |= ( pSrc->fixed << 15 );
- frameshtons(pCtx, pBuf, tmp109__, 0);
+ tmp110__ = 0U;
+ tmp110__ |= ( pSrc->size << 0 );
+ tmp110__ |= ( pSrc->fixed << 15 );
+ frameshtons(pCtx, pBuf, tmp110__, 0);
*pnConsumed += 2;
pBuf += 2;
nBuf -= 2 ;
@@ -27274,7 +27479,6 @@ tANI_U32 dot11fPackIeEDCAParamSet(tpAniSirGlobal pCtx,
tANI_U8* pIeLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U8 tmp110__;
tANI_U8 tmp111__;
tANI_U8 tmp112__;
tANI_U8 tmp113__;
@@ -27282,6 +27486,7 @@ tANI_U32 dot11fPackIeEDCAParamSet(tpAniSirGlobal pCtx,
tANI_U8 tmp115__;
tANI_U8 tmp116__;
tANI_U8 tmp117__;
+ tANI_U8 tmp118__;
nNeeded += 18;
while ( pSrc->present )
{
@@ -27296,79 +27501,79 @@ tANI_U32 dot11fPackIeEDCAParamSet(tpAniSirGlobal pCtx,
*pBuf = pSrc->reserved;
*pnConsumed += 1;
pBuf += 1;
- tmp110__ = 0U;
- tmp110__ |= ( pSrc->acbe_aifsn << 0 );
- tmp110__ |= ( pSrc->acbe_acm << 4 );
- tmp110__ |= ( pSrc->acbe_aci << 5 );
- tmp110__ |= ( pSrc->unused1 << 7 );
- *pBuf = tmp110__;
- *pnConsumed += 1;
- pBuf += 1;
- nBuf -= 1 ;
tmp111__ = 0U;
- tmp111__ |= ( pSrc->acbe_acwmin << 0 );
- tmp111__ |= ( pSrc->acbe_acwmax << 4 );
+ tmp111__ |= ( pSrc->acbe_aifsn << 0 );
+ tmp111__ |= ( pSrc->acbe_acm << 4 );
+ tmp111__ |= ( pSrc->acbe_aci << 5 );
+ tmp111__ |= ( pSrc->unused1 << 7 );
*pBuf = tmp111__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
- frameshtons(pCtx, pBuf, pSrc->acbe_txoplimit, 0);
- *pnConsumed += 2;
- pBuf += 2;
tmp112__ = 0U;
- tmp112__ |= ( pSrc->acbk_aifsn << 0 );
- tmp112__ |= ( pSrc->acbk_acm << 4 );
- tmp112__ |= ( pSrc->acbk_aci << 5 );
- tmp112__ |= ( pSrc->unused2 << 7 );
+ tmp112__ |= ( pSrc->acbe_acwmin << 0 );
+ tmp112__ |= ( pSrc->acbe_acwmax << 4 );
*pBuf = tmp112__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
+ frameshtons(pCtx, pBuf, pSrc->acbe_txoplimit, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
tmp113__ = 0U;
- tmp113__ |= ( pSrc->acbk_acwmin << 0 );
- tmp113__ |= ( pSrc->acbk_acwmax << 4 );
+ tmp113__ |= ( pSrc->acbk_aifsn << 0 );
+ tmp113__ |= ( pSrc->acbk_acm << 4 );
+ tmp113__ |= ( pSrc->acbk_aci << 5 );
+ tmp113__ |= ( pSrc->unused2 << 7 );
*pBuf = tmp113__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
- frameshtons(pCtx, pBuf, pSrc->acbk_txoplimit, 0);
- *pnConsumed += 2;
- pBuf += 2;
tmp114__ = 0U;
- tmp114__ |= ( pSrc->acvi_aifsn << 0 );
- tmp114__ |= ( pSrc->acvi_acm << 4 );
- tmp114__ |= ( pSrc->acvi_aci << 5 );
- tmp114__ |= ( pSrc->unused3 << 7 );
+ tmp114__ |= ( pSrc->acbk_acwmin << 0 );
+ tmp114__ |= ( pSrc->acbk_acwmax << 4 );
*pBuf = tmp114__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
+ frameshtons(pCtx, pBuf, pSrc->acbk_txoplimit, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
tmp115__ = 0U;
- tmp115__ |= ( pSrc->acvi_acwmin << 0 );
- tmp115__ |= ( pSrc->acvi_acwmax << 4 );
+ tmp115__ |= ( pSrc->acvi_aifsn << 0 );
+ tmp115__ |= ( pSrc->acvi_acm << 4 );
+ tmp115__ |= ( pSrc->acvi_aci << 5 );
+ tmp115__ |= ( pSrc->unused3 << 7 );
*pBuf = tmp115__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
- frameshtons(pCtx, pBuf, pSrc->acvi_txoplimit, 0);
- *pnConsumed += 2;
- pBuf += 2;
tmp116__ = 0U;
- tmp116__ |= ( pSrc->acvo_aifsn << 0 );
- tmp116__ |= ( pSrc->acvo_acm << 4 );
- tmp116__ |= ( pSrc->acvo_aci << 5 );
- tmp116__ |= ( pSrc->unused4 << 7 );
+ tmp116__ |= ( pSrc->acvi_acwmin << 0 );
+ tmp116__ |= ( pSrc->acvi_acwmax << 4 );
*pBuf = tmp116__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
+ frameshtons(pCtx, pBuf, pSrc->acvi_txoplimit, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
tmp117__ = 0U;
- tmp117__ |= ( pSrc->acvo_acwmin << 0 );
- tmp117__ |= ( pSrc->acvo_acwmax << 4 );
+ tmp117__ |= ( pSrc->acvo_aifsn << 0 );
+ tmp117__ |= ( pSrc->acvo_acm << 4 );
+ tmp117__ |= ( pSrc->acvo_aci << 5 );
+ tmp117__ |= ( pSrc->unused4 << 7 );
*pBuf = tmp117__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
+ tmp118__ = 0U;
+ tmp118__ |= ( pSrc->acvo_acwmin << 0 );
+ tmp118__ |= ( pSrc->acvo_acwmax << 4 );
+ *pBuf = tmp118__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
frameshtons(pCtx, pBuf, pSrc->acvo_txoplimit, 0);
*pnConsumed += 2;
// fieldsEndFlag = 1
@@ -27391,7 +27596,7 @@ tANI_U32 dot11fPackIeERPInfo(tpAniSirGlobal pCtx,
tANI_U8* pIeLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U8 tmp118__;
+ tANI_U8 tmp119__;
nNeeded += 1;
while ( pSrc->present )
{
@@ -27400,12 +27605,12 @@ tANI_U32 dot11fPackIeERPInfo(tpAniSirGlobal pCtx,
++pBuf; ++(*pnConsumed);
pIeLen = pBuf;
++pBuf; ++(*pnConsumed);
- tmp118__ = 0U;
- tmp118__ |= ( pSrc->non_erp_present << 0 );
- tmp118__ |= ( pSrc->use_prot << 1 );
- tmp118__ |= ( pSrc->barker_preamble << 2 );
- tmp118__ |= ( pSrc->unused << 3 );
- *pBuf = tmp118__;
+ tmp119__ = 0U;
+ tmp119__ |= ( pSrc->non_erp_present << 0 );
+ tmp119__ |= ( pSrc->use_prot << 1 );
+ tmp119__ |= ( pSrc->barker_preamble << 2 );
+ tmp119__ |= ( pSrc->unused << 3 );
+ *pBuf = tmp119__;
*pnConsumed += 1;
// fieldsEndFlag = 1
nBuf -= 1 ;
@@ -27466,7 +27671,7 @@ tANI_U32 dot11fPackIeESERadMgmtCap(tpAniSirGlobal pCtx,
tANI_U8* pIeLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U8 tmp119__;
+ tANI_U8 tmp120__;
nNeeded += 2;
while ( pSrc->present )
{
@@ -27486,10 +27691,10 @@ tANI_U32 dot11fPackIeESERadMgmtCap(tpAniSirGlobal pCtx,
*pBuf = pSrc->mgmt_state;
*pnConsumed += 1;
pBuf += 1;
- tmp119__ = 0U;
- tmp119__ |= ( pSrc->mbssid_mask << 0 );
- tmp119__ |= ( pSrc->reserved << 3 );
- *pBuf = tmp119__;
+ tmp120__ = 0U;
+ tmp120__ |= ( pSrc->mbssid_mask << 0 );
+ tmp120__ |= ( pSrc->reserved << 3 );
+ *pBuf = tmp120__;
*pnConsumed += 1;
// fieldsEndFlag = 1
nBuf -= 1 ;
@@ -27880,7 +28085,7 @@ tANI_U32 dot11fPackIeFTInfo(tpAniSirGlobal pCtx,
tANI_U8* pIeLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U16 tmp120__;
+ tANI_U16 tmp121__;
tANI_U32 status = DOT11F_PARSE_SUCCESS;
status = dot11fGetPackedIEFTInfo(pCtx, pSrc, &nNeeded);
if ( ! DOT11F_SUCCEEDED( status ) ) return status;
@@ -27891,10 +28096,10 @@ tANI_U32 dot11fPackIeFTInfo(tpAniSirGlobal pCtx,
++pBuf; --nBuf; ++(*pnConsumed);
pIeLen = pBuf;
++pBuf; --nBuf; ++(*pnConsumed);
- tmp120__ = 0U;
- tmp120__ |= ( pSrc->reserved << 0 );
- tmp120__ |= ( pSrc->IECount << 8 );
- frameshtons(pCtx, pBuf, tmp120__, 0);
+ tmp121__ = 0U;
+ tmp121__ |= ( pSrc->reserved << 0 );
+ tmp121__ |= ( pSrc->IECount << 8 );
+ frameshtons(pCtx, pBuf, tmp121__, 0);
*pnConsumed += 2;
pBuf += 2;
nBuf -= 2 ;
@@ -27933,7 +28138,7 @@ tANI_U32 dot11fPackIeHT2040BSSCoexistence(tpAniSirGlobal pCtx,
tANI_U8* pIeLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U8 tmp121__;
+ tANI_U8 tmp122__;
nNeeded += 1;
while ( pSrc->present )
{
@@ -27942,14 +28147,14 @@ tANI_U32 dot11fPackIeHT2040BSSCoexistence(tpAniSirGlobal pCtx,
++pBuf; ++(*pnConsumed);
pIeLen = pBuf;
++pBuf; ++(*pnConsumed);
- tmp121__ = 0U;
- tmp121__ |= ( pSrc->infoRequest << 0 );
- tmp121__ |= ( pSrc->fortyMHzIntolerant << 1 );
- tmp121__ |= ( pSrc->twentyMHzBssWidthReq << 2 );
- tmp121__ |= ( pSrc->obssScanExemptionReq << 3 );
- tmp121__ |= ( pSrc->obssScanExemptionGrant << 4 );
- tmp121__ |= ( pSrc->unused << 5 );
- *pBuf = tmp121__;
+ tmp122__ = 0U;
+ tmp122__ |= ( pSrc->infoRequest << 0 );
+ tmp122__ |= ( pSrc->fortyMHzIntolerant << 1 );
+ tmp122__ |= ( pSrc->twentyMHzBssWidthReq << 2 );
+ tmp122__ |= ( pSrc->obssScanExemptionReq << 3 );
+ tmp122__ |= ( pSrc->obssScanExemptionGrant << 4 );
+ tmp122__ |= ( pSrc->unused << 5 );
+ *pBuf = tmp122__;
*pnConsumed += 1;
// fieldsEndFlag = 1
nBuf -= 1 ;
@@ -28005,11 +28210,11 @@ tANI_U32 dot11fPackIeHTCaps(tpAniSirGlobal pCtx,
tANI_U8* pIeLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U16 tmp122__;
- tANI_U8 tmp123__;
- tANI_U16 tmp124__;
- tANI_U32 tmp125__;
- tANI_U8 tmp126__;
+ tANI_U16 tmp123__;
+ tANI_U8 tmp124__;
+ tANI_U16 tmp125__;
+ tANI_U32 tmp126__;
+ tANI_U8 tmp127__;
nNeeded += (pSrc->num_rsvd + 26);
while ( pSrc->present )
{
@@ -28018,77 +28223,77 @@ tANI_U32 dot11fPackIeHTCaps(tpAniSirGlobal pCtx,
++pBuf; ++(*pnConsumed);
pIeLen = pBuf;
++pBuf; ++(*pnConsumed);
- tmp122__ = 0U;
- tmp122__ |= ( pSrc->advCodingCap << 0 );
- tmp122__ |= ( pSrc->supportedChannelWidthSet << 1 );
- tmp122__ |= ( pSrc->mimoPowerSave << 2 );
- tmp122__ |= ( pSrc->greenField << 4 );
- tmp122__ |= ( pSrc->shortGI20MHz << 5 );
- tmp122__ |= ( pSrc->shortGI40MHz << 6 );
- tmp122__ |= ( pSrc->txSTBC << 7 );
- tmp122__ |= ( pSrc->rxSTBC << 8 );
- tmp122__ |= ( pSrc->delayedBA << 10 );
- tmp122__ |= ( pSrc->maximalAMSDUsize << 11 );
- tmp122__ |= ( pSrc->dsssCckMode40MHz << 12 );
- tmp122__ |= ( pSrc->psmp << 13 );
- tmp122__ |= ( pSrc->stbcControlFrame << 14 );
- tmp122__ |= ( pSrc->lsigTXOPProtection << 15 );
- frameshtons(pCtx, pBuf, tmp122__, 0);
+ tmp123__ = 0U;
+ tmp123__ |= ( pSrc->advCodingCap << 0 );
+ tmp123__ |= ( pSrc->supportedChannelWidthSet << 1 );
+ tmp123__ |= ( pSrc->mimoPowerSave << 2 );
+ tmp123__ |= ( pSrc->greenField << 4 );
+ tmp123__ |= ( pSrc->shortGI20MHz << 5 );
+ tmp123__ |= ( pSrc->shortGI40MHz << 6 );
+ tmp123__ |= ( pSrc->txSTBC << 7 );
+ tmp123__ |= ( pSrc->rxSTBC << 8 );
+ tmp123__ |= ( pSrc->delayedBA << 10 );
+ tmp123__ |= ( pSrc->maximalAMSDUsize << 11 );
+ tmp123__ |= ( pSrc->dsssCckMode40MHz << 12 );
+ tmp123__ |= ( pSrc->psmp << 13 );
+ tmp123__ |= ( pSrc->stbcControlFrame << 14 );
+ tmp123__ |= ( pSrc->lsigTXOPProtection << 15 );
+ frameshtons(pCtx, pBuf, tmp123__, 0);
*pnConsumed += 2;
pBuf += 2;
nBuf -= 2 ;
- tmp123__ = 0U;
- tmp123__ |= ( pSrc->maxRxAMPDUFactor << 0 );
- tmp123__ |= ( pSrc->mpduDensity << 2 );
- tmp123__ |= ( pSrc->reserved1 << 5 );
- *pBuf = tmp123__;
+ tmp124__ = 0U;
+ tmp124__ |= ( pSrc->maxRxAMPDUFactor << 0 );
+ tmp124__ |= ( pSrc->mpduDensity << 2 );
+ tmp124__ |= ( pSrc->reserved1 << 5 );
+ *pBuf = tmp124__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
DOT11F_MEMCPY(pCtx, pBuf, pSrc->supportedMCSSet, 16);
*pnConsumed += 16;
pBuf += 16;
- tmp124__ = 0U;
- tmp124__ |= ( pSrc->pco << 0 );
- tmp124__ |= ( pSrc->transitionTime << 1 );
- tmp124__ |= ( pSrc->reserved2 << 3 );
- tmp124__ |= ( pSrc->mcsFeedback << 8 );
- tmp124__ |= ( pSrc->reserved3 << 10 );
- frameshtons(pCtx, pBuf, tmp124__, 0);
+ tmp125__ = 0U;
+ tmp125__ |= ( pSrc->pco << 0 );
+ tmp125__ |= ( pSrc->transitionTime << 1 );
+ tmp125__ |= ( pSrc->reserved2 << 3 );
+ tmp125__ |= ( pSrc->mcsFeedback << 8 );
+ tmp125__ |= ( pSrc->reserved3 << 10 );
+ frameshtons(pCtx, pBuf, tmp125__, 0);
*pnConsumed += 2;
pBuf += 2;
nBuf -= 2 ;
- tmp125__ = 0U;
- tmp125__ |= ( pSrc->txBF << 0 );
- tmp125__ |= ( pSrc->rxStaggeredSounding << 1 );
- tmp125__ |= ( pSrc->txStaggeredSounding << 2 );
- tmp125__ |= ( pSrc->rxZLF << 3 );
- tmp125__ |= ( pSrc->txZLF << 4 );
- tmp125__ |= ( pSrc->implicitTxBF << 5 );
- tmp125__ |= ( pSrc->calibration << 6 );
- tmp125__ |= ( pSrc->explicitCSITxBF << 8 );
- tmp125__ |= ( pSrc->explicitUncompressedSteeringMatrix << 9 );
- tmp125__ |= ( pSrc->explicitBFCSIFeedback << 10 );
- tmp125__ |= ( pSrc->explicitUncompressedSteeringMatrixFeedback << 13 );
- tmp125__ |= ( pSrc->explicitCompressedSteeringMatrixFeedback << 16 );
- tmp125__ |= ( pSrc->csiNumBFAntennae << 19 );
- tmp125__ |= ( pSrc->uncompressedSteeringMatrixBFAntennae << 21 );
- tmp125__ |= ( pSrc->compressedSteeringMatrixBFAntennae << 23 );
- tmp125__ |= ( pSrc->reserved4 << 25 );
- frameshtonl(pCtx, pBuf, tmp125__, 0);
+ tmp126__ = 0U;
+ tmp126__ |= ( pSrc->txBF << 0 );
+ tmp126__ |= ( pSrc->rxStaggeredSounding << 1 );
+ tmp126__ |= ( pSrc->txStaggeredSounding << 2 );
+ tmp126__ |= ( pSrc->rxZLF << 3 );
+ tmp126__ |= ( pSrc->txZLF << 4 );
+ tmp126__ |= ( pSrc->implicitTxBF << 5 );
+ tmp126__ |= ( pSrc->calibration << 6 );
+ tmp126__ |= ( pSrc->explicitCSITxBF << 8 );
+ tmp126__ |= ( pSrc->explicitUncompressedSteeringMatrix << 9 );
+ tmp126__ |= ( pSrc->explicitBFCSIFeedback << 10 );
+ tmp126__ |= ( pSrc->explicitUncompressedSteeringMatrixFeedback << 13 );
+ tmp126__ |= ( pSrc->explicitCompressedSteeringMatrixFeedback << 16 );
+ tmp126__ |= ( pSrc->csiNumBFAntennae << 19 );
+ tmp126__ |= ( pSrc->uncompressedSteeringMatrixBFAntennae << 21 );
+ tmp126__ |= ( pSrc->compressedSteeringMatrixBFAntennae << 23 );
+ tmp126__ |= ( pSrc->reserved4 << 25 );
+ frameshtonl(pCtx, pBuf, tmp126__, 0);
*pnConsumed += 4;
pBuf += 4;
nBuf -= 4 ;
- tmp126__ = 0U;
- tmp126__ |= ( pSrc->antennaSelection << 0 );
- tmp126__ |= ( pSrc->explicitCSIFeedbackTx << 1 );
- tmp126__ |= ( pSrc->antennaIndicesFeedbackTx << 2 );
- tmp126__ |= ( pSrc->explicitCSIFeedback << 3 );
- tmp126__ |= ( pSrc->antennaIndicesFeedback << 4 );
- tmp126__ |= ( pSrc->rxAS << 5 );
- tmp126__ |= ( pSrc->txSoundingPPDUs << 6 );
- tmp126__ |= ( pSrc->reserved5 << 7 );
- *pBuf = tmp126__;
+ tmp127__ = 0U;
+ tmp127__ |= ( pSrc->antennaSelection << 0 );
+ tmp127__ |= ( pSrc->explicitCSIFeedbackTx << 1 );
+ tmp127__ |= ( pSrc->antennaIndicesFeedbackTx << 2 );
+ tmp127__ |= ( pSrc->explicitCSIFeedback << 3 );
+ tmp127__ |= ( pSrc->antennaIndicesFeedback << 4 );
+ tmp127__ |= ( pSrc->rxAS << 5 );
+ tmp127__ |= ( pSrc->txSoundingPPDUs << 6 );
+ tmp127__ |= ( pSrc->reserved5 << 7 );
+ *pBuf = tmp127__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
@@ -28114,9 +28319,9 @@ tANI_U32 dot11fPackIeHTInfo(tpAniSirGlobal pCtx,
tANI_U8* pIeLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U8 tmp127__;
- tANI_U16 tmp128__;
+ tANI_U8 tmp128__;
tANI_U16 tmp129__;
+ tANI_U16 tmp130__;
nNeeded += (pSrc->num_rsvd + 22);
while ( pSrc->present )
{
@@ -28128,35 +28333,35 @@ tANI_U32 dot11fPackIeHTInfo(tpAniSirGlobal pCtx,
*pBuf = pSrc->primaryChannel;
*pnConsumed += 1;
pBuf += 1;
- tmp127__ = 0U;
- tmp127__ |= ( pSrc->secondaryChannelOffset << 0 );
- tmp127__ |= ( pSrc->recommendedTxWidthSet << 2 );
- tmp127__ |= ( pSrc->rifsMode << 3 );
- tmp127__ |= ( pSrc->controlledAccessOnly << 4 );
- tmp127__ |= ( pSrc->serviceIntervalGranularity << 5 );
- *pBuf = tmp127__;
+ tmp128__ = 0U;
+ tmp128__ |= ( pSrc->secondaryChannelOffset << 0 );
+ tmp128__ |= ( pSrc->recommendedTxWidthSet << 2 );
+ tmp128__ |= ( pSrc->rifsMode << 3 );
+ tmp128__ |= ( pSrc->controlledAccessOnly << 4 );
+ tmp128__ |= ( pSrc->serviceIntervalGranularity << 5 );
+ *pBuf = tmp128__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
- tmp128__ = 0U;
- tmp128__ |= ( pSrc->opMode << 0 );
- tmp128__ |= ( pSrc->nonGFDevicesPresent << 2 );
- tmp128__ |= ( pSrc->transmitBurstLimit << 3 );
- tmp128__ |= ( pSrc->obssNonHTStaPresent << 4 );
- tmp128__ |= ( pSrc->reserved << 5 );
- frameshtons(pCtx, pBuf, tmp128__, 0);
+ tmp129__ = 0U;
+ tmp129__ |= ( pSrc->opMode << 0 );
+ tmp129__ |= ( pSrc->nonGFDevicesPresent << 2 );
+ tmp129__ |= ( pSrc->transmitBurstLimit << 3 );
+ tmp129__ |= ( pSrc->obssNonHTStaPresent << 4 );
+ tmp129__ |= ( pSrc->reserved << 5 );
+ frameshtons(pCtx, pBuf, tmp129__, 0);
*pnConsumed += 2;
pBuf += 2;
nBuf -= 2 ;
- tmp129__ = 0U;
- tmp129__ |= ( pSrc->basicSTBCMCS << 0 );
- tmp129__ |= ( pSrc->dualCTSProtection << 7 );
- tmp129__ |= ( pSrc->secondaryBeacon << 8 );
- tmp129__ |= ( pSrc->lsigTXOPProtectionFullSupport << 9 );
- tmp129__ |= ( pSrc->pcoActive << 10 );
- tmp129__ |= ( pSrc->pcoPhase << 11 );
- tmp129__ |= ( pSrc->reserved2 << 12 );
- frameshtons(pCtx, pBuf, tmp129__, 0);
+ tmp130__ = 0U;
+ tmp130__ |= ( pSrc->basicSTBCMCS << 0 );
+ tmp130__ |= ( pSrc->dualCTSProtection << 7 );
+ tmp130__ |= ( pSrc->secondaryBeacon << 8 );
+ tmp130__ |= ( pSrc->lsigTXOPProtectionFullSupport << 9 );
+ tmp130__ |= ( pSrc->pcoActive << 10 );
+ tmp130__ |= ( pSrc->pcoPhase << 11 );
+ tmp130__ |= ( pSrc->reserved2 << 12 );
+ frameshtons(pCtx, pBuf, tmp130__, 0);
*pnConsumed += 2;
pBuf += 2;
nBuf -= 2 ;
@@ -28251,9 +28456,9 @@ tANI_U32 dot11fPackIeMeasurementReport(tpAniSirGlobal pCtx,
tANI_U8* pIeLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U8 tmp130__;
tANI_U8 tmp131__;
tANI_U8 tmp132__;
+ tANI_U8 tmp133__;
tANI_U32 status = DOT11F_PARSE_SUCCESS;
status = dot11fGetPackedIEMeasurementReport(pCtx, pSrc, &nNeeded);
if ( ! DOT11F_SUCCEEDED( status ) ) return status;
@@ -28267,12 +28472,12 @@ tANI_U32 dot11fPackIeMeasurementReport(tpAniSirGlobal pCtx,
*pBuf = pSrc->token;
*pnConsumed += 1;
pBuf += 1;
- tmp130__ = 0U;
- tmp130__ |= ( pSrc->late << 0 );
- tmp130__ |= ( pSrc->incapable << 1 );
- tmp130__ |= ( pSrc->refused << 2 );
- tmp130__ |= ( pSrc->unused << 3 );
- *pBuf = tmp130__;
+ tmp131__ = 0U;
+ tmp131__ |= ( pSrc->late << 0 );
+ tmp131__ |= ( pSrc->incapable << 1 );
+ tmp131__ |= ( pSrc->refused << 2 );
+ tmp131__ |= ( pSrc->unused << 3 );
+ *pBuf = tmp131__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
@@ -28292,14 +28497,14 @@ tANI_U32 dot11fPackIeMeasurementReport(tpAniSirGlobal pCtx,
frameshtons(pCtx, pBuf, pSrc->report.Basic.meas_duration, 0);
*pnConsumed += 2;
pBuf += 2;
- tmp131__ = 0U;
- tmp131__ |= ( pSrc->report.Basic.bss << 0 );
- tmp131__ |= ( pSrc->report.Basic.ofdm_preamble << 1 );
- tmp131__ |= ( pSrc->report.Basic.unid_signal << 2 );
- tmp131__ |= ( pSrc->report.Basic.rader << 3 );
- tmp131__ |= ( pSrc->report.Basic.unmeasured << 4 );
- tmp131__ |= ( pSrc->report.Basic.unused << 5 );
- *pBuf = tmp131__;
+ tmp132__ = 0U;
+ tmp132__ |= ( pSrc->report.Basic.bss << 0 );
+ tmp132__ |= ( pSrc->report.Basic.ofdm_preamble << 1 );
+ tmp132__ |= ( pSrc->report.Basic.unid_signal << 2 );
+ tmp132__ |= ( pSrc->report.Basic.rader << 3 );
+ tmp132__ |= ( pSrc->report.Basic.unmeasured << 4 );
+ tmp132__ |= ( pSrc->report.Basic.unused << 5 );
+ *pBuf = tmp132__;
*pnConsumed += 1;
// fieldsEndFlag = 1
nBuf -= 1 ;
@@ -28366,10 +28571,10 @@ tANI_U32 dot11fPackIeMeasurementReport(tpAniSirGlobal pCtx,
frameshtons(pCtx, pBuf, pSrc->report.Beacon.meas_duration, 0);
*pnConsumed += 2;
pBuf += 2;
- tmp132__ = 0U;
- tmp132__ |= ( pSrc->report.Beacon.condensed_PHY << 0 );
- tmp132__ |= ( pSrc->report.Beacon.reported_frame_type << 7 );
- *pBuf = tmp132__;
+ tmp133__ = 0U;
+ tmp133__ |= ( pSrc->report.Beacon.condensed_PHY << 0 );
+ tmp133__ |= ( pSrc->report.Beacon.reported_frame_type << 7 );
+ *pBuf = tmp133__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
@@ -28418,7 +28623,7 @@ tANI_U32 dot11fPackIeMeasurementRequest(tpAniSirGlobal pCtx,
tANI_U8* pIeLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U8 tmp133__;
+ tANI_U8 tmp134__;
tANI_U32 status = DOT11F_PARSE_SUCCESS;
status = dot11fGetPackedIEMeasurementRequest(pCtx, pSrc, &nNeeded);
if ( ! DOT11F_SUCCEEDED( status ) ) return status;
@@ -28432,14 +28637,14 @@ tANI_U32 dot11fPackIeMeasurementRequest(tpAniSirGlobal pCtx,
*pBuf = pSrc->measurement_token;
*pnConsumed += 1;
pBuf += 1;
- tmp133__ = 0U;
- tmp133__ |= ( pSrc->parallel << 0 );
- tmp133__ |= ( pSrc->enable << 1 );
- tmp133__ |= ( pSrc->request << 2 );
- tmp133__ |= ( pSrc->report << 3 );
- tmp133__ |= ( pSrc->durationMandatory << 4 );
- tmp133__ |= ( pSrc->unused << 5 );
- *pBuf = tmp133__;
+ tmp134__ = 0U;
+ tmp134__ |= ( pSrc->parallel << 0 );
+ tmp134__ |= ( pSrc->enable << 1 );
+ tmp134__ |= ( pSrc->request << 2 );
+ tmp134__ |= ( pSrc->report << 3 );
+ tmp134__ |= ( pSrc->durationMandatory << 4 );
+ tmp134__ |= ( pSrc->unused << 5 );
+ *pBuf = tmp134__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
@@ -28528,7 +28733,7 @@ tANI_U32 dot11fPackIeMobilityDomain(tpAniSirGlobal pCtx,
tANI_U8* pIeLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U8 tmp134__;
+ tANI_U8 tmp135__;
nNeeded += 3;
while ( pSrc->present )
{
@@ -28540,11 +28745,11 @@ tANI_U32 dot11fPackIeMobilityDomain(tpAniSirGlobal pCtx,
frameshtons(pCtx, pBuf, pSrc->MDID, 0);
*pnConsumed += 2;
pBuf += 2;
- tmp134__ = 0U;
- tmp134__ |= ( pSrc->overDSCap << 0 );
- tmp134__ |= ( pSrc->resourceReqCap << 1 );
- tmp134__ |= ( pSrc->reserved << 2 );
- *pBuf = tmp134__;
+ tmp135__ = 0U;
+ tmp135__ |= ( pSrc->overDSCap << 0 );
+ tmp135__ |= ( pSrc->resourceReqCap << 1 );
+ tmp135__ |= ( pSrc->reserved << 2 );
+ *pBuf = tmp135__;
*pnConsumed += 1;
// fieldsEndFlag = 1
nBuf -= 1 ;
@@ -28567,8 +28772,8 @@ tANI_U32 dot11fPackIeNeighborReport(tpAniSirGlobal pCtx,
tANI_U8* pIeLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U8 tmp135__;
tANI_U8 tmp136__;
+ tANI_U8 tmp137__;
tANI_U32 status = DOT11F_PARSE_SUCCESS;
status = dot11fGetPackedIENeighborReport(pCtx, pSrc, &nNeeded);
if ( ! DOT11F_SUCCEEDED( status ) ) return status;
@@ -28582,24 +28787,24 @@ tANI_U32 dot11fPackIeNeighborReport(tpAniSirGlobal pCtx,
DOT11F_MEMCPY(pCtx, pBuf, pSrc->bssid, 6);
*pnConsumed += 6;
pBuf += 6;
- tmp135__ = 0U;
- tmp135__ |= ( pSrc->APReachability << 0 );
- tmp135__ |= ( pSrc->Security << 2 );
- tmp135__ |= ( pSrc->KeyScope << 3 );
- tmp135__ |= ( pSrc->SpecMgmtCap << 4 );
- tmp135__ |= ( pSrc->QosCap << 5 );
- tmp135__ |= ( pSrc->apsd << 6 );
- tmp135__ |= ( pSrc->rrm << 7 );
- *pBuf = tmp135__;
+ tmp136__ = 0U;
+ tmp136__ |= ( pSrc->APReachability << 0 );
+ tmp136__ |= ( pSrc->Security << 2 );
+ tmp136__ |= ( pSrc->KeyScope << 3 );
+ tmp136__ |= ( pSrc->SpecMgmtCap << 4 );
+ tmp136__ |= ( pSrc->QosCap << 5 );
+ tmp136__ |= ( pSrc->apsd << 6 );
+ tmp136__ |= ( pSrc->rrm << 7 );
+ *pBuf = tmp136__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
- tmp136__ = 0U;
- tmp136__ |= ( pSrc->DelayedBA << 0 );
- tmp136__ |= ( pSrc->ImmBA << 1 );
- tmp136__ |= ( pSrc->MobilityDomain << 2 );
- tmp136__ |= ( pSrc->reserved << 3 );
- *pBuf = tmp136__;
+ tmp137__ = 0U;
+ tmp137__ |= ( pSrc->DelayedBA << 0 );
+ tmp137__ |= ( pSrc->ImmBA << 1 );
+ tmp137__ |= ( pSrc->MobilityDomain << 2 );
+ tmp137__ |= ( pSrc->reserved << 3 );
+ *pBuf = tmp137__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
@@ -28689,7 +28894,7 @@ tANI_U32 dot11fPackIeOperatingMode(tpAniSirGlobal pCtx,
tANI_U8* pIeLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U8 tmp137__;
+ tANI_U8 tmp138__;
nNeeded += 1;
while ( pSrc->present )
{
@@ -28698,12 +28903,12 @@ tANI_U32 dot11fPackIeOperatingMode(tpAniSirGlobal pCtx,
++pBuf; ++(*pnConsumed);
pIeLen = pBuf;
++pBuf; ++(*pnConsumed);
- tmp137__ = 0U;
- tmp137__ |= ( pSrc->chanWidth << 0 );
- tmp137__ |= ( pSrc->reserved << 2 );
- tmp137__ |= ( pSrc->rxNSS << 4 );
- tmp137__ |= ( pSrc->rxNSSType << 7 );
- *pBuf = tmp137__;
+ tmp138__ = 0U;
+ tmp138__ |= ( pSrc->chanWidth << 0 );
+ tmp138__ |= ( pSrc->reserved << 2 );
+ tmp138__ |= ( pSrc->rxNSS << 4 );
+ tmp138__ |= ( pSrc->rxNSSType << 7 );
+ *pBuf = tmp138__;
*pnConsumed += 1;
// fieldsEndFlag = 1
nBuf -= 1 ;
@@ -29657,7 +29862,7 @@ tANI_U32 dot11fPackIePUBufferStatus(tpAniSirGlobal pCtx,
tANI_U8* pIeLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U8 tmp138__;
+ tANI_U8 tmp139__;
nNeeded += 1;
while ( pSrc->present )
{
@@ -29666,13 +29871,13 @@ tANI_U32 dot11fPackIePUBufferStatus(tpAniSirGlobal pCtx,
++pBuf; ++(*pnConsumed);
pIeLen = pBuf;
++pBuf; ++(*pnConsumed);
- tmp138__ = 0U;
- tmp138__ |= ( pSrc->ac_bk_traffic_aval << 0 );
- tmp138__ |= ( pSrc->ac_be_traffic_aval << 1 );
- tmp138__ |= ( pSrc->ac_vi_traffic_aval << 2 );
- tmp138__ |= ( pSrc->ac_vo_traffic_aval << 3 );
- tmp138__ |= ( pSrc->reserved << 4 );
- *pBuf = tmp138__;
+ tmp139__ = 0U;
+ tmp139__ |= ( pSrc->ac_bk_traffic_aval << 0 );
+ tmp139__ |= ( pSrc->ac_be_traffic_aval << 1 );
+ tmp139__ |= ( pSrc->ac_vi_traffic_aval << 2 );
+ tmp139__ |= ( pSrc->ac_vo_traffic_aval << 3 );
+ tmp139__ |= ( pSrc->reserved << 4 );
+ *pBuf = tmp139__;
*pnConsumed += 1;
// fieldsEndFlag = 1
nBuf -= 1 ;
@@ -29794,7 +29999,7 @@ tANI_U32 dot11fPackIeQOSCapsAp(tpAniSirGlobal pCtx,
tANI_U8* pIeLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U8 tmp139__;
+ tANI_U8 tmp140__;
nNeeded += 1;
while ( pSrc->present )
{
@@ -29803,13 +30008,13 @@ tANI_U32 dot11fPackIeQOSCapsAp(tpAniSirGlobal pCtx,
++pBuf; ++(*pnConsumed);
pIeLen = pBuf;
++pBuf; ++(*pnConsumed);
- tmp139__ = 0U;
- tmp139__ |= ( pSrc->count << 0 );
- tmp139__ |= ( pSrc->qack << 4 );
- tmp139__ |= ( pSrc->qreq << 5 );
- tmp139__ |= ( pSrc->txopreq << 6 );
- tmp139__ |= ( pSrc->reserved << 7 );
- *pBuf = tmp139__;
+ tmp140__ = 0U;
+ tmp140__ |= ( pSrc->count << 0 );
+ tmp140__ |= ( pSrc->qack << 4 );
+ tmp140__ |= ( pSrc->qreq << 5 );
+ tmp140__ |= ( pSrc->txopreq << 6 );
+ tmp140__ |= ( pSrc->reserved << 7 );
+ *pBuf = tmp140__;
*pnConsumed += 1;
// fieldsEndFlag = 1
nBuf -= 1 ;
@@ -29832,7 +30037,7 @@ tANI_U32 dot11fPackIeQOSCapsStation(tpAniSirGlobal pCtx,
tANI_U8* pIeLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U8 tmp140__;
+ tANI_U8 tmp141__;
nNeeded += 1;
while ( pSrc->present )
{
@@ -29841,15 +30046,15 @@ tANI_U32 dot11fPackIeQOSCapsStation(tpAniSirGlobal pCtx,
++pBuf; ++(*pnConsumed);
pIeLen = pBuf;
++pBuf; ++(*pnConsumed);
- tmp140__ = 0U;
- tmp140__ |= ( pSrc->acvo_uapsd << 0 );
- tmp140__ |= ( pSrc->acvi_uapsd << 1 );
- tmp140__ |= ( pSrc->acbk_uapsd << 2 );
- tmp140__ |= ( pSrc->acbe_uapsd << 3 );
- tmp140__ |= ( pSrc->qack << 4 );
- tmp140__ |= ( pSrc->max_sp_length << 5 );
- tmp140__ |= ( pSrc->more_data_ack << 7 );
- *pBuf = tmp140__;
+ tmp141__ = 0U;
+ tmp141__ |= ( pSrc->acvo_uapsd << 0 );
+ tmp141__ |= ( pSrc->acvi_uapsd << 1 );
+ tmp141__ |= ( pSrc->acbk_uapsd << 2 );
+ tmp141__ |= ( pSrc->acbe_uapsd << 3 );
+ tmp141__ |= ( pSrc->qack << 4 );
+ tmp141__ |= ( pSrc->max_sp_length << 5 );
+ tmp141__ |= ( pSrc->more_data_ack << 7 );
+ *pBuf = tmp141__;
*pnConsumed += 1;
// fieldsEndFlag = 1
nBuf -= 1 ;
@@ -30353,9 +30558,9 @@ tANI_U32 dot11fPackIeVHTCaps(tpAniSirGlobal pCtx,
tANI_U8* pIeLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U32 tmp141__;
- tANI_U16 tmp142__;
+ tANI_U32 tmp142__;
tANI_U16 tmp143__;
+ tANI_U16 tmp144__;
nNeeded += 12;
while ( pSrc->present )
{
@@ -30364,48 +30569,48 @@ tANI_U32 dot11fPackIeVHTCaps(tpAniSirGlobal pCtx,
++pBuf; ++(*pnConsumed);
pIeLen = pBuf;
++pBuf; ++(*pnConsumed);
- tmp141__ = 0U;
- tmp141__ |= ( pSrc->maxMPDULen << 0 );
- tmp141__ |= ( pSrc->supportedChannelWidthSet << 2 );
- tmp141__ |= ( pSrc->ldpcCodingCap << 4 );
- tmp141__ |= ( pSrc->shortGI80MHz << 5 );
- tmp141__ |= ( pSrc->shortGI160and80plus80MHz << 6 );
- tmp141__ |= ( pSrc->txSTBC << 7 );
- tmp141__ |= ( pSrc->rxSTBC << 8 );
- tmp141__ |= ( pSrc->suBeamFormerCap << 11 );
- tmp141__ |= ( pSrc->suBeamformeeCap << 12 );
- tmp141__ |= ( pSrc->csnofBeamformerAntSup << 13 );
- tmp141__ |= ( pSrc->numSoundingDim << 16 );
- tmp141__ |= ( pSrc->muBeamformerCap << 19 );
- tmp141__ |= ( pSrc->muBeamformeeCap << 20 );
- tmp141__ |= ( pSrc->vhtTXOPPS << 21 );
- tmp141__ |= ( pSrc->htcVHTCap << 22 );
- tmp141__ |= ( pSrc->maxAMPDULenExp << 23 );
- tmp141__ |= ( pSrc->vhtLinkAdaptCap << 26 );
- tmp141__ |= ( pSrc->rxAntPattern << 28 );
- tmp141__ |= ( pSrc->txAntPattern << 29 );
- tmp141__ |= ( pSrc->reserved1 << 30 );
- frameshtonl(pCtx, pBuf, tmp141__, 0);
+ tmp142__ = 0U;
+ tmp142__ |= ( pSrc->maxMPDULen << 0 );
+ tmp142__ |= ( pSrc->supportedChannelWidthSet << 2 );
+ tmp142__ |= ( pSrc->ldpcCodingCap << 4 );
+ tmp142__ |= ( pSrc->shortGI80MHz << 5 );
+ tmp142__ |= ( pSrc->shortGI160and80plus80MHz << 6 );
+ tmp142__ |= ( pSrc->txSTBC << 7 );
+ tmp142__ |= ( pSrc->rxSTBC << 8 );
+ tmp142__ |= ( pSrc->suBeamFormerCap << 11 );
+ tmp142__ |= ( pSrc->suBeamformeeCap << 12 );
+ tmp142__ |= ( pSrc->csnofBeamformerAntSup << 13 );
+ tmp142__ |= ( pSrc->numSoundingDim << 16 );
+ tmp142__ |= ( pSrc->muBeamformerCap << 19 );
+ tmp142__ |= ( pSrc->muBeamformeeCap << 20 );
+ tmp142__ |= ( pSrc->vhtTXOPPS << 21 );
+ tmp142__ |= ( pSrc->htcVHTCap << 22 );
+ tmp142__ |= ( pSrc->maxAMPDULenExp << 23 );
+ tmp142__ |= ( pSrc->vhtLinkAdaptCap << 26 );
+ tmp142__ |= ( pSrc->rxAntPattern << 28 );
+ tmp142__ |= ( pSrc->txAntPattern << 29 );
+ tmp142__ |= ( pSrc->reserved1 << 30 );
+ frameshtonl(pCtx, pBuf, tmp142__, 0);
*pnConsumed += 4;
pBuf += 4;
nBuf -= 4 ;
frameshtons(pCtx, pBuf, pSrc->rxMCSMap, 0);
*pnConsumed += 2;
pBuf += 2;
- tmp142__ = 0U;
- tmp142__ |= ( pSrc->rxHighSupDataRate << 0 );
- tmp142__ |= ( pSrc->reserved2 << 13 );
- frameshtons(pCtx, pBuf, tmp142__, 0);
+ tmp143__ = 0U;
+ tmp143__ |= ( pSrc->rxHighSupDataRate << 0 );
+ tmp143__ |= ( pSrc->reserved2 << 13 );
+ frameshtons(pCtx, pBuf, tmp143__, 0);
*pnConsumed += 2;
pBuf += 2;
nBuf -= 2 ;
frameshtons(pCtx, pBuf, pSrc->txMCSMap, 0);
*pnConsumed += 2;
pBuf += 2;
- tmp143__ = 0U;
- tmp143__ |= ( pSrc->txSupDataRate << 0 );
- tmp143__ |= ( pSrc->reserved3 << 13 );
- frameshtons(pCtx, pBuf, tmp143__, 0);
+ tmp144__ = 0U;
+ tmp144__ |= ( pSrc->txSupDataRate << 0 );
+ tmp144__ |= ( pSrc->reserved3 << 13 );
+ frameshtons(pCtx, pBuf, tmp144__, 0);
*pnConsumed += 2;
// fieldsEndFlag = 1
nBuf -= 2 ;
@@ -30509,7 +30714,7 @@ tANI_U32 dot11fPackIeWAPI(tpAniSirGlobal pCtx,
tANI_U8* pIeLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U16 tmp144__;
+ tANI_U16 tmp145__;
tANI_U32 status = DOT11F_PARSE_SUCCESS;
status = dot11fGetPackedIEWAPI(pCtx, pSrc, &nNeeded);
if ( ! DOT11F_SUCCEEDED( status ) ) return status;
@@ -30538,10 +30743,10 @@ tANI_U32 dot11fPackIeWAPI(tpAniSirGlobal pCtx,
DOT11F_MEMCPY(pCtx, pBuf, pSrc->multicast_cipher_suite, 4);
*pnConsumed += 4;
pBuf += 4;
- tmp144__ = 0U;
- tmp144__ |= ( pSrc->preauth << 0 );
- tmp144__ |= ( pSrc->reserved << 1 );
- frameshtons(pCtx, pBuf, tmp144__, 0);
+ tmp145__ = 0U;
+ tmp145__ |= ( pSrc->preauth << 0 );
+ tmp145__ |= ( pSrc->reserved << 1 );
+ frameshtons(pCtx, pBuf, tmp145__, 0);
*pnConsumed += 2;
pBuf += 2;
nBuf -= 2 ;
@@ -30684,7 +30889,7 @@ tANI_U32 dot11fPackIeWMMCaps(tpAniSirGlobal pCtx,
tANI_U8* pIeLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U8 tmp145__;
+ tANI_U8 tmp146__;
nNeeded += 2;
while ( pSrc->present )
{
@@ -30706,13 +30911,13 @@ tANI_U32 dot11fPackIeWMMCaps(tpAniSirGlobal pCtx,
*pBuf = pSrc->version;
*pnConsumed += 1;
pBuf += 1;
- tmp145__ = 0U;
- tmp145__ |= ( pSrc->reserved << 0 );
- tmp145__ |= ( pSrc->qack << 4 );
- tmp145__ |= ( pSrc->queue_request << 5 );
- tmp145__ |= ( pSrc->txop_request << 6 );
- tmp145__ |= ( pSrc->more_ack << 7 );
- *pBuf = tmp145__;
+ tmp146__ = 0U;
+ tmp146__ |= ( pSrc->reserved << 0 );
+ tmp146__ |= ( pSrc->qack << 4 );
+ tmp146__ |= ( pSrc->queue_request << 5 );
+ tmp146__ |= ( pSrc->txop_request << 6 );
+ tmp146__ |= ( pSrc->more_ack << 7 );
+ *pBuf = tmp146__;
*pnConsumed += 1;
// fieldsEndFlag = 1
nBuf -= 1 ;
@@ -30735,7 +30940,7 @@ tANI_U32 dot11fPackIeWMMInfoAp(tpAniSirGlobal pCtx,
tANI_U8* pIeLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U8 tmp146__;
+ tANI_U8 tmp147__;
nNeeded += 2;
while ( pSrc->present )
{
@@ -30757,11 +30962,11 @@ tANI_U32 dot11fPackIeWMMInfoAp(tpAniSirGlobal pCtx,
*pBuf = pSrc->version;
*pnConsumed += 1;
pBuf += 1;
- tmp146__ = 0U;
- tmp146__ |= ( pSrc->param_set_count << 0 );
- tmp146__ |= ( pSrc->reserved << 4 );
- tmp146__ |= ( pSrc->uapsd << 7 );
- *pBuf = tmp146__;
+ tmp147__ = 0U;
+ tmp147__ |= ( pSrc->param_set_count << 0 );
+ tmp147__ |= ( pSrc->reserved << 4 );
+ tmp147__ |= ( pSrc->uapsd << 7 );
+ *pBuf = tmp147__;
*pnConsumed += 1;
// fieldsEndFlag = 1
nBuf -= 1 ;
@@ -30784,7 +30989,7 @@ tANI_U32 dot11fPackIeWMMInfoStation(tpAniSirGlobal pCtx,
tANI_U8* pIeLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U8 tmp147__;
+ tANI_U8 tmp148__;
nNeeded += 2;
while ( pSrc->present )
{
@@ -30806,15 +31011,15 @@ tANI_U32 dot11fPackIeWMMInfoStation(tpAniSirGlobal pCtx,
*pBuf = pSrc->version;
*pnConsumed += 1;
pBuf += 1;
- tmp147__ = 0U;
- tmp147__ |= ( pSrc->acvo_uapsd << 0 );
- tmp147__ |= ( pSrc->acvi_uapsd << 1 );
- tmp147__ |= ( pSrc->acbk_uapsd << 2 );
- tmp147__ |= ( pSrc->acbe_uapsd << 3 );
- tmp147__ |= ( pSrc->reserved1 << 4 );
- tmp147__ |= ( pSrc->max_sp_length << 5 );
- tmp147__ |= ( pSrc->reserved2 << 7 );
- *pBuf = tmp147__;
+ tmp148__ = 0U;
+ tmp148__ |= ( pSrc->acvo_uapsd << 0 );
+ tmp148__ |= ( pSrc->acvi_uapsd << 1 );
+ tmp148__ |= ( pSrc->acbk_uapsd << 2 );
+ tmp148__ |= ( pSrc->acbe_uapsd << 3 );
+ tmp148__ |= ( pSrc->reserved1 << 4 );
+ tmp148__ |= ( pSrc->max_sp_length << 5 );
+ tmp148__ |= ( pSrc->reserved2 << 7 );
+ *pBuf = tmp148__;
*pnConsumed += 1;
// fieldsEndFlag = 1
nBuf -= 1 ;
@@ -30837,7 +31042,6 @@ tANI_U32 dot11fPackIeWMMParams(tpAniSirGlobal pCtx,
tANI_U8* pIeLen = 0;
tANI_U32 nConsumedOnEntry = *pnConsumed;
tANI_U32 nNeeded = 0U;
- tANI_U8 tmp148__;
tANI_U8 tmp149__;
tANI_U8 tmp150__;
tANI_U8 tmp151__;
@@ -30845,6 +31049,7 @@ tANI_U32 dot11fPackIeWMMParams(tpAniSirGlobal pCtx,
tANI_U8 tmp153__;
tANI_U8 tmp154__;
tANI_U8 tmp155__;
+ tANI_U8 tmp156__;
nNeeded += 19;
while ( pSrc->present )
{
@@ -30872,79 +31077,79 @@ tANI_U32 dot11fPackIeWMMParams(tpAniSirGlobal pCtx,
*pBuf = pSrc->reserved2;
*pnConsumed += 1;
pBuf += 1;
- tmp148__ = 0U;
- tmp148__ |= ( pSrc->acbe_aifsn << 0 );
- tmp148__ |= ( pSrc->acbe_acm << 4 );
- tmp148__ |= ( pSrc->acbe_aci << 5 );
- tmp148__ |= ( pSrc->unused1 << 7 );
- *pBuf = tmp148__;
- *pnConsumed += 1;
- pBuf += 1;
- nBuf -= 1 ;
tmp149__ = 0U;
- tmp149__ |= ( pSrc->acbe_acwmin << 0 );
- tmp149__ |= ( pSrc->acbe_acwmax << 4 );
+ tmp149__ |= ( pSrc->acbe_aifsn << 0 );
+ tmp149__ |= ( pSrc->acbe_acm << 4 );
+ tmp149__ |= ( pSrc->acbe_aci << 5 );
+ tmp149__ |= ( pSrc->unused1 << 7 );
*pBuf = tmp149__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
- frameshtons(pCtx, pBuf, pSrc->acbe_txoplimit, 0);
- *pnConsumed += 2;
- pBuf += 2;
tmp150__ = 0U;
- tmp150__ |= ( pSrc->acbk_aifsn << 0 );
- tmp150__ |= ( pSrc->acbk_acm << 4 );
- tmp150__ |= ( pSrc->acbk_aci << 5 );
- tmp150__ |= ( pSrc->unused2 << 7 );
+ tmp150__ |= ( pSrc->acbe_acwmin << 0 );
+ tmp150__ |= ( pSrc->acbe_acwmax << 4 );
*pBuf = tmp150__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
+ frameshtons(pCtx, pBuf, pSrc->acbe_txoplimit, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
tmp151__ = 0U;
- tmp151__ |= ( pSrc->acbk_acwmin << 0 );
- tmp151__ |= ( pSrc->acbk_acwmax << 4 );
+ tmp151__ |= ( pSrc->acbk_aifsn << 0 );
+ tmp151__ |= ( pSrc->acbk_acm << 4 );
+ tmp151__ |= ( pSrc->acbk_aci << 5 );
+ tmp151__ |= ( pSrc->unused2 << 7 );
*pBuf = tmp151__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
- frameshtons(pCtx, pBuf, pSrc->acbk_txoplimit, 0);
- *pnConsumed += 2;
- pBuf += 2;
tmp152__ = 0U;
- tmp152__ |= ( pSrc->acvi_aifsn << 0 );
- tmp152__ |= ( pSrc->acvi_acm << 4 );
- tmp152__ |= ( pSrc->acvi_aci << 5 );
- tmp152__ |= ( pSrc->unused3 << 7 );
+ tmp152__ |= ( pSrc->acbk_acwmin << 0 );
+ tmp152__ |= ( pSrc->acbk_acwmax << 4 );
*pBuf = tmp152__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
+ frameshtons(pCtx, pBuf, pSrc->acbk_txoplimit, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
tmp153__ = 0U;
- tmp153__ |= ( pSrc->acvi_acwmin << 0 );
- tmp153__ |= ( pSrc->acvi_acwmax << 4 );
+ tmp153__ |= ( pSrc->acvi_aifsn << 0 );
+ tmp153__ |= ( pSrc->acvi_acm << 4 );
+ tmp153__ |= ( pSrc->acvi_aci << 5 );
+ tmp153__ |= ( pSrc->unused3 << 7 );
*pBuf = tmp153__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
- frameshtons(pCtx, pBuf, pSrc->acvi_txoplimit, 0);
- *pnConsumed += 2;
- pBuf += 2;
tmp154__ = 0U;
- tmp154__ |= ( pSrc->acvo_aifsn << 0 );
- tmp154__ |= ( pSrc->acvo_acm << 4 );
- tmp154__ |= ( pSrc->acvo_aci << 5 );
- tmp154__ |= ( pSrc->unused4 << 7 );
+ tmp154__ |= ( pSrc->acvi_acwmin << 0 );
+ tmp154__ |= ( pSrc->acvi_acwmax << 4 );
*pBuf = tmp154__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
+ frameshtons(pCtx, pBuf, pSrc->acvi_txoplimit, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
tmp155__ = 0U;
- tmp155__ |= ( pSrc->acvo_acwmin << 0 );
- tmp155__ |= ( pSrc->acvo_acwmax << 4 );
+ tmp155__ |= ( pSrc->acvo_aifsn << 0 );
+ tmp155__ |= ( pSrc->acvo_acm << 4 );
+ tmp155__ |= ( pSrc->acvo_aci << 5 );
+ tmp155__ |= ( pSrc->unused4 << 7 );
*pBuf = tmp155__;
*pnConsumed += 1;
pBuf += 1;
nBuf -= 1 ;
+ tmp156__ = 0U;
+ tmp156__ |= ( pSrc->acvo_acwmin << 0 );
+ tmp156__ |= ( pSrc->acvo_acwmax << 4 );
+ *pBuf = tmp156__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
frameshtons(pCtx, pBuf, pSrc->acvo_txoplimit, 0);
*pnConsumed += 2;
// fieldsEndFlag = 1
@@ -31484,6 +31689,69 @@ tANI_U32 dot11fPackIeWscReassocRes(tpAniSirGlobal pCtx,
return status;
} /* End dot11fPackIeWscReassocRes. */
+tANI_U32 dot11fPackIehs20vendor_ie(tpAniSirGlobal pCtx,
+ tDot11fIEhs20vendor_ie *pSrc,
+ tANI_U8 *pBuf,
+ tANI_U32 nBuf,
+ tANI_U32 *pnConsumed)
+{
+ tANI_U8* pIeLen = 0;
+ tANI_U32 nConsumedOnEntry = *pnConsumed;
+ tANI_U32 nNeeded = 0U;
+ tANI_U8 tmp157__;
+ tANI_U32 status = DOT11F_PARSE_SUCCESS;
+ status = dot11fGetPackedIEhs20vendor_ie(pCtx, pSrc, &nNeeded);
+ if ( ! DOT11F_SUCCEEDED( status ) ) return status;
+ while ( pSrc->present )
+ {
+ if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 221;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x6f;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x9a;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x10;
+ ++pBuf; ++(*pnConsumed);
+ tmp157__ = 0U;
+ tmp157__ |= ( pSrc->dgaf_dis << 0 );
+ tmp157__ |= ( pSrc->hs_id_present << 1 );
+ tmp157__ |= ( pSrc->reserved << 3 );
+ tmp157__ |= ( pSrc->release_num << 4 );
+ *pBuf = tmp157__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ if ( pSrc->hs_id_present ) {
+ switch (pSrc->hs_id_present)
+ {
+ case 1:
+ frameshtons(pCtx, pBuf, pSrc->hs_id.pps_mo.pps_mo_id, 0);
+ *pnConsumed += 2;
+ // fieldsEndFlag = 1
+ break;
+ case 2:
+ frameshtons(pCtx, pBuf, pSrc->hs_id.anqp_domain.anqp_domain_id, 0);
+ *pnConsumed += 2;
+ // fieldsEndFlag = 1
+ break;
+ }
+ }
+ else break;
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen)
+ {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return status;
+} /* End dot11fPackIehs20vendor_ie. */
+
tANI_U32 dot11fPackAddBAReq(tpAniSirGlobal pCtx, tDot11fAddBAReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed)
{
tANI_U32 i = 0;
@@ -32638,6 +32906,27 @@ tANI_U32 dot11fPackAssocRequest(tpAniSirGlobal pCtx, tDot11fAssocRequest *pFrm,
FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_dscp_exceptions: %d.\n"), pFrm->QosMapSet.num_dscp_exceptions);
FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->QosMapSet.dscp_exceptions, pFrm->QosMapSet.num_dscp_exceptions);
}
+ FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("hs20vendor_ie:\n"));
+ if (!pFrm->hs20vendor_ie.present)
+ {
+ FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n"));
+ }
+ else
+ {
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("dgaf_dis (1): %d\n"), pFrm->hs20vendor_ie.dgaf_dis);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("hs_id_present (2): %d\n"), pFrm->hs20vendor_ie.hs_id_present);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved (1): %d\n"), pFrm->hs20vendor_ie.reserved);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("release_num (4): %d\n"), pFrm->hs20vendor_ie.release_num);
+ switch (pFrm->hs20vendor_ie.hs_id_present)
+ {
+ case 1:
+ FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.pps_mo.pps_mo_id, 2);
+ break;
+ case 2:
+ FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.anqp_domain.anqp_domain_id, 2);
+ break;
+ }
+ }
FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("to:\n"));
FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), pBuf, nBuf);
}
@@ -35196,6 +35485,27 @@ tANI_U32 dot11fPackBeacon(tpAniSirGlobal pCtx, tDot11fBeacon *pFrm, tANI_U8 *pBu
FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2);
FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2);
}
+ FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("hs20vendor_ie:\n"));
+ if (!pFrm->hs20vendor_ie.present)
+ {
+ FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n"));
+ }
+ else
+ {
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("dgaf_dis (1): %d\n"), pFrm->hs20vendor_ie.dgaf_dis);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("hs_id_present (2): %d\n"), pFrm->hs20vendor_ie.hs_id_present);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (1): %d\n"), pFrm->hs20vendor_ie.reserved);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("release_num (4): %d\n"), pFrm->hs20vendor_ie.release_num);
+ switch (pFrm->hs20vendor_ie.hs_id_present)
+ {
+ case 1:
+ FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.pps_mo.pps_mo_id, 2);
+ break;
+ case 2:
+ FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.anqp_domain.anqp_domain_id, 2);
+ break;
+ }
+ }
FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("to:\n"));
FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), pBuf, nBuf);
}
@@ -36178,6 +36488,27 @@ tANI_U32 dot11fPackBeacon2(tpAniSirGlobal pCtx, tDot11fBeacon2 *pFrm, tANI_U8 *p
FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2);
FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2);
}
+ FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("hs20vendor_ie:\n"));
+ if (!pFrm->hs20vendor_ie.present)
+ {
+ FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n"));
+ }
+ else
+ {
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("dgaf_dis (1): %d\n"), pFrm->hs20vendor_ie.dgaf_dis);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("hs_id_present (2): %d\n"), pFrm->hs20vendor_ie.hs_id_present);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (1): %d\n"), pFrm->hs20vendor_ie.reserved);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("release_num (4): %d\n"), pFrm->hs20vendor_ie.release_num);
+ switch (pFrm->hs20vendor_ie.hs_id_present)
+ {
+ case 1:
+ FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.pps_mo.pps_mo_id, 2);
+ break;
+ case 2:
+ FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.anqp_domain.anqp_domain_id, 2);
+ break;
+ }
+ }
FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("to:\n"));
FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), pBuf, nBuf);
}
@@ -37341,6 +37672,27 @@ tANI_U32 dot11fPackBeaconIEs(tpAniSirGlobal pCtx, tDot11fBeaconIEs *pFrm, tANI_U
FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2);
FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2);
}
+ FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("hs20vendor_ie:\n"));
+ if (!pFrm->hs20vendor_ie.present)
+ {
+ FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n"));
+ }
+ else
+ {
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("dgaf_dis (1): %d\n"), pFrm->hs20vendor_ie.dgaf_dis);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("hs_id_present (2): %d\n"), pFrm->hs20vendor_ie.hs_id_present);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (1): %d\n"), pFrm->hs20vendor_ie.reserved);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("release_num (4): %d\n"), pFrm->hs20vendor_ie.release_num);
+ switch (pFrm->hs20vendor_ie.hs_id_present)
+ {
+ case 1:
+ FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.pps_mo.pps_mo_id, 2);
+ break;
+ case 2:
+ FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.anqp_domain.anqp_domain_id, 2);
+ break;
+ }
+ }
FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("to:\n"));
FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), pBuf, nBuf);
}
@@ -40450,6 +40802,27 @@ tANI_U32 dot11fPackProbeResponse(tpAniSirGlobal pCtx, tDot11fProbeResponse *pFrm
FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2);
FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2);
}
+ FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("hs20vendor_ie:\n"));
+ if (!pFrm->hs20vendor_ie.present)
+ {
+ FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n"));
+ }
+ else
+ {
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("dgaf_dis (1): %d\n"), pFrm->hs20vendor_ie.dgaf_dis);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("hs_id_present (2): %d\n"), pFrm->hs20vendor_ie.hs_id_present);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (1): %d\n"), pFrm->hs20vendor_ie.reserved);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("release_num (4): %d\n"), pFrm->hs20vendor_ie.release_num);
+ switch (pFrm->hs20vendor_ie.hs_id_present)
+ {
+ case 1:
+ FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.pps_mo.pps_mo_id, 2);
+ break;
+ case 2:
+ FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.anqp_domain.anqp_domain_id, 2);
+ break;
+ }
+ }
FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("to:\n"));
FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), pBuf, nBuf);
}
@@ -41791,6 +42164,27 @@ tANI_U32 dot11fPackReAssocRequest(tpAniSirGlobal pCtx, tDot11fReAssocRequest *pF
FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_dscp_exceptions: %d.\n"), pFrm->QosMapSet.num_dscp_exceptions);
FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->QosMapSet.dscp_exceptions, pFrm->QosMapSet.num_dscp_exceptions);
}
+ FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("hs20vendor_ie:\n"));
+ if (!pFrm->hs20vendor_ie.present)
+ {
+ FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n"));
+ }
+ else
+ {
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("dgaf_dis (1): %d\n"), pFrm->hs20vendor_ie.dgaf_dis);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("hs_id_present (2): %d\n"), pFrm->hs20vendor_ie.hs_id_present);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (1): %d\n"), pFrm->hs20vendor_ie.reserved);
+ FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("release_num (4): %d\n"), pFrm->hs20vendor_ie.release_num);
+ switch (pFrm->hs20vendor_ie.hs_id_present)
+ {
+ case 1:
+ FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.pps_mo.pps_mo_id, 2);
+ break;
+ case 2:
+ FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.anqp_domain.anqp_domain_id, 2);
+ break;
+ }
+ }
FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("to:\n"));
FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), pBuf, nBuf);
}
@@ -45460,6 +45854,9 @@ static tANI_U32 PackCore(tpAniSirGlobal pCtx,
case SigIeWscReassocRes:
status |= dot11fPackIeWscReassocRes(pCtx, ( tDot11fIEWscReassocRes* )(pSrc + pIe->offset + sizeof(tDot11fIEWscReassocRes) * i ), pBufRemaining, nBufRemaining, &len);
break;
+ case SigIehs20vendor_ie:
+ status |= dot11fPackIehs20vendor_ie(pCtx, ( tDot11fIEhs20vendor_ie* )(pSrc + pIe->offset + sizeof(tDot11fIEhs20vendor_ie) * i ), pBufRemaining, nBufRemaining, &len);
+ break;
default:
FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR-- I don"
"'t know about the IE %d; this is most likely a b"
diff --git a/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/macTrace.c b/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/macTrace.c
index 0da70dc30c0..ba7c97aba79 100644
--- a/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/macTrace.c
+++ b/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/macTrace.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -137,6 +137,9 @@ tANI_U8* macTraceGetNeighbourRoamState(tANI_U16 neighbourRoamState)
CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING);
CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE);
#endif /* WLAN_FEATURE_VOWIFI_11R */
+ #ifdef WLAN_FEATURE_LFR_MBB
+ CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_MBB_PREAUTH_REASSOC);
+ #endif
CASE_RETURN_STRING(eNEIGHBOR_STATE_MAX);
default:
@@ -572,7 +575,13 @@ tANI_U8* macTraceGetSmeMsgString( tANI_U16 smeMsg )
CASE_RETURN_STRING(eWNI_SME_UPDATE_MAX_RATE_IND);
CASE_RETURN_STRING(eWNI_SME_SET_TDLS_2040_BSSCOEX_REQ);
CASE_RETURN_STRING(eWNI_SME_REGISTER_MGMT_FRAME_CB);
+#ifdef WLAN_FEATURE_LFR_MBB
+ CASE_RETURN_STRING(eWNI_SME_MBB_PRE_AUTH_REASSOC_REQ);
+ CASE_RETURN_STRING(eWNI_SME_MBB_PRE_AUTH_REASSOC_RSP);
+#endif
CASE_RETURN_STRING(eWNI_SME_MSG_TYPES_END);
+ CASE_RETURN_STRING(eWNI_SME_CAP_TSF_REQ);
+ CASE_RETURN_STRING(eWNI_SME_GET_TSF_REQ);
default:
return( (tANI_U8*)"UNKNOWN" );
break;
@@ -906,10 +915,19 @@ tANI_U8* macTraceGetWdaMsgString( tANI_U16 wdaMsg )
CASE_RETURN_STRING(WDA_MON_STOP_REQ);
CASE_RETURN_STRING(WDA_SPOOF_MAC_ADDR_REQ);
CASE_RETURN_STRING(WDA_LOST_LINK_PARAMS_IND);
+#ifdef DHCP_SERVER_OFFLOAD
+ CASE_RETURN_STRING(WDA_SET_DHCP_SERVER_OFFLOAD_REQ);
+#endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+ CASE_RETURN_STRING(WDA_SET_MDNS_OFFLOAD_CMD);
+ CASE_RETURN_STRING(WDA_SET_MDNS_FQDN_CMD);
+ CASE_RETURN_STRING(WDA_SET_MDNS_RESPONSE_CMD);
+ CASE_RETURN_STRING(WDA_GET_MDNS_STATUS_CMD);
+#endif
+ CASE_RETURN_STRING(WDA_CAP_TSF_REQ);
+ CASE_RETURN_STRING(WDA_GET_TSF_REQ);
CASE_RETURN_STRING(WDA_SET_ARP_STATS_REQ);
CASE_RETURN_STRING(WDA_GET_ARP_STATS_REQ);
- CASE_RETURN_STRING(WDA_TRIGGER_ADD_BA_REQ);
- CASE_RETURN_STRING(WDA_GET_CON_STATUS);
default:
return((tANI_U8*) "UNKNOWN" );
break;
@@ -971,7 +989,15 @@ tANI_U8* macTraceGetLimMsgString( tANI_U16 limMsg )
CASE_RETURN_STRING(SIR_LIM_DISASSOC_ACK_TIMEOUT);
CASE_RETURN_STRING(SIR_LIM_DEAUTH_ACK_TIMEOUT);
CASE_RETURN_STRING(SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT);
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ CASE_RETURN_STRING(SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT);
+ CASE_RETURN_STRING(SIR_LIM_REASSOC_MBB_RSP_TIMEOUT);
+
+#endif
+
CASE_RETURN_STRING(SIR_LIM_AUTH_RETRY_TIMEOUT);
+
CASE_RETURN_STRING(SIR_LIM_MSG_TYPES_END);
CASE_RETURN_STRING(LIM_MLM_SCAN_REQ);
CASE_RETURN_STRING(LIM_MLM_SCAN_CNF);
diff --git a/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/parserApi.c b/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/parserApi.c
index a3f30f0653f..142be12bda6 100644
--- a/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/parserApi.c
+++ b/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/parserApi.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -50,6 +50,30 @@
#include "rrmApi.h"
#endif
+#define DOT11F_RSN_VERSION 1 /* current supported version */
+#define DOT11F_RSN_OUI_SIZE 4
+#define DOT11F_RSN_CSE_NULL 0x00
+#define DOT11F_RSN_CSE_WEP40 0x01
+#define DOT11F_RSN_CSE_TKIP 0x02
+#define DOT11F_RSN_CSE_WRAP 0x03
+#define DOT11F_RSN_CSE_CCMP 0x04
+#define DOT11F_RSN_CSE_WEP104 0x05
+#define DOT11F_RSN_CSE_AES_CMAC 0x06
+
+static const tANI_U8 sirRSNOui[][ DOT11F_RSN_OUI_SIZE ] = {
+ { 0x00, 0x0F, 0xAC, 0x00 }, /* group cipher */
+ { 0x00, 0x0F, 0xAC, 0x01 }, /* WEP-40 or RSN */
+ { 0x00, 0x0F, 0xAC, 0x02 }, /* TKIP or RSN-PSK */
+ { 0x00, 0x0F, 0xAC, 0x03 }, /* Reserved */
+ { 0x00, 0x0F, 0xAC, 0x04 }, /* AES-CCMP */
+ { 0x00, 0x0F, 0xAC, 0x05 }, /* WEP-104 */
+ { 0x00, 0x40, 0x96, 0x00 }, /* CCKM */
+ /* BIP (encryption type) or RSN-PSK-SHA256 (authentication type) */
+ { 0x00, 0x0F, 0xAC, 0x06 },
+ /* RSN-8021X-SHA256 (authentication type) */
+ { 0x00, 0x0F, 0xAC, 0x05 }
+};
+
////////////////////////////////////////////////////////////////////////
@@ -2380,6 +2404,7 @@ tSirRetStatus sirConvertProbeFrame2Struct(tpAniSirGlobal pMac,
vos_mem_copy( &pProbeResp->VHTExtBssLoad, &pr->VHTExtBssLoad, sizeof( tDot11fIEVHTExtBssLoad) );
}
#endif
+ sir_copy_hs20_ie(&pProbeResp->hs20vendor_ie, &pr->hs20vendor_ie);
vos_mem_vfree(pr);
return eSIR_SUCCESS;
@@ -2708,7 +2733,7 @@ sirConvertAssocRespFrame2Struct(tpAniSirGlobal pMac,
#endif
#ifdef WLAN_FEATURE_VOWIFI_11R
- if (ar.num_RICDataDesc <= 2) {
+ if (ar.num_RICDataDesc && ar.num_RICDataDesc <= 2) {
for (cnt=0; cnt < ar.num_RICDataDesc; cnt++) {
if (ar.RICDataDesc[cnt].present) {
vos_mem_copy( &pAssocRsp->RICData[cnt], &ar.RICDataDesc[cnt],
@@ -3493,6 +3518,8 @@ sirParseBeaconIE(tpAniSirGlobal pMac,
vos_mem_copy( &pBeaconStruct->ExtCap, &pBies->ExtCap,
sizeof(tDot11fIEExtCap));
}
+ sir_copy_hs20_ie(&pBeaconStruct->hs20vendor_ie, &pBies->hs20vendor_ie);
+
vos_mem_free(pBies);
@@ -3798,6 +3825,7 @@ sirConvertBeaconFrame2Struct(tpAniSirGlobal pMac,
&pBeacon->OBSSScanParameters,
sizeof( tDot11fIEOBSSScanParameters));
}
+ sir_copy_hs20_ie(&pBeaconStruct->hs20vendor_ie, &pBeacon->hs20vendor_ie);
vos_mem_vfree(pBeacon);
return eSIR_SUCCESS;
@@ -5456,4 +5484,137 @@ void PopulateDot11fTimeoutInterval( tpAniSirGlobal pMac,
pDot11f->timeoutType = type;
pDot11f->timeoutValue = value;
}
+#ifdef SAP_AUTH_OFFLOAD
+tSirRetStatus
+sap_auth_offload_construct_rsn_opaque( tDot11fIERSN *pdot11f_rsn,
+ tDot11fIERSNOpaque *pdot11f)
+{
+ tANI_U32 data_len=0;
+ tANI_U8 *ptr;
+ tANI_U32 element_len=0;
+ tANI_U32 count=0;
+ ptr = (tANI_U8 *)pdot11f->data;
+ if (pdot11f_rsn->present)
+ {
+ pdot11f->present = pdot11f_rsn->present;
+ element_len = sizeof(pdot11f_rsn->version);
+ vos_mem_copy(ptr, &pdot11f_rsn->version, element_len);
+ ptr += element_len;
+ data_len += element_len;
+ element_len = sizeof(pdot11f_rsn->gp_cipher_suite);
+ vos_mem_copy(ptr, pdot11f_rsn->gp_cipher_suite, element_len);
+ ptr += element_len;
+ data_len += element_len;
+
+ if (pdot11f_rsn->pwise_cipher_suite_count)
+ {
+ element_len = sizeof(pdot11f_rsn->pwise_cipher_suite_count);
+ vos_mem_copy(ptr,
+ &pdot11f_rsn->pwise_cipher_suite_count,
+ element_len);
+ ptr += element_len;
+ data_len += element_len;
+ for (count = 0; count < pdot11f_rsn->pwise_cipher_suite_count;
+ count++)
+ {
+ element_len = DOT11F_RSN_OUI_SIZE;
+ vos_mem_copy(ptr,
+ &pdot11f_rsn->pwise_cipher_suites[count][0],
+ element_len);
+ ptr += element_len;
+ data_len += element_len;
+ }
+ }
+
+ if (pdot11f_rsn->akm_suite_count)
+ {
+ element_len = sizeof(pdot11f_rsn->akm_suite_count);
+ vos_mem_copy(ptr, &pdot11f_rsn->akm_suite_count, element_len);
+ ptr += element_len;
+ data_len += element_len;
+ for (count = 0; count < pdot11f_rsn->akm_suite_count; count++)
+ {
+ element_len = DOT11F_RSN_OUI_SIZE;
+ vos_mem_copy(ptr,
+ &pdot11f_rsn->akm_suites[count][0],
+ element_len);
+ ptr += element_len;
+ data_len += element_len;
+ }
+ }
+
+ element_len = sizeof(pdot11f_rsn->RSN_Cap);
+ vos_mem_copy(ptr, pdot11f_rsn->RSN_Cap, element_len);
+ ptr += element_len;
+ data_len += element_len;
+ }
+ pdot11f->num_data = data_len;
+ return eSIR_SUCCESS;
+}
+
+void
+sap_auth_offload_update_rsn_ie( tpAniSirGlobal pmac,
+ tDot11fIERSNOpaque *pdot11f)
+{
+ tDot11fIERSN *pdot11f_rsn;
+ pdot11f_rsn = vos_mem_malloc(sizeof(tDot11fIERSN));
+ vos_mem_set(pdot11f_rsn, sizeof(tDot11fIERSN), 0);
+ /* Assign RSN IE for Software AP Authentication offload security */
+ if (pmac->sap_auth_offload && pmac->sap_auth_offload_sec_type)
+ {
+ switch (pmac->sap_auth_offload_sec_type)
+ {
+ case eSIR_OFFLOAD_WPA2PSK_CCMP:
+ /* Only Support one kind of Cipher Suit for
+ * Software AP authentication offload
+ */
+ pdot11f_rsn->present = 1;
+ pdot11f_rsn->version = 1;
+ vos_mem_copy(pdot11f_rsn->gp_cipher_suite,
+ &sirRSNOui[DOT11F_RSN_CSE_CCMP][0],
+ DOT11F_RSN_OUI_SIZE);
+ pdot11f_rsn->pwise_cipher_suite_count = 1;
+ vos_mem_copy(&(pdot11f_rsn->pwise_cipher_suites[0][0]),
+ &sirRSNOui[DOT11F_RSN_CSE_CCMP][0],
+ DOT11F_RSN_OUI_SIZE);
+ pdot11f_rsn->akm_suite_count = 1;
+ vos_mem_copy(&(pdot11f_rsn->akm_suites[0][0]),
+ &sirRSNOui[DOT11F_RSN_CSE_TKIP][0],
+ DOT11F_RSN_OUI_SIZE);
+ pdot11f_rsn->pmkid_count = 0;
+ /* Construct RSN IE into RSNOpaque*/
+ sap_auth_offload_construct_rsn_opaque(pdot11f_rsn, pdot11f);
+ break;
+ default:
+ dot11fLog( pmac, LOGE,
+ FL("The security type is not definied for "
+ "Software AP authentication offload!\n"));
+ break;
+ }
+ }
+}
+#endif /* SAP_AUTH_OFFLOAD */
+
+/**
+ * sir_copy_hs20_ie() - Update HS 2.0 Information Element.
+ * @dest: dest HS IE buffer to be updated
+ * @src: src HS IE buffer
+ *
+ * Update HS2.0 IE info from src to dest
+ *
+ * Return: void
+ */
+void sir_copy_hs20_ie(tDot11fIEhs20vendor_ie *dest, tDot11fIEhs20vendor_ie *src)
+{
+ if (src->present) {
+ vos_mem_copy(dest, src,
+ sizeof(tDot11fIEhs20vendor_ie) -
+ sizeof(src->hs_id));
+ if (src->hs_id_present)
+ vos_mem_copy(&dest->hs_id,
+ &src->hs_id,
+ sizeof(src->hs_id));
+ }
+}
+
// parserApi.c ends here.
diff --git a/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/utilsParser.c b/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/utilsParser.c
index 3292b5c4f72..32f19925b22 100644
--- a/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/utilsParser.c
+++ b/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/utilsParser.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2015, 2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -691,6 +691,8 @@ void ConvertQosMapsetFrame(tpAniSirGlobal pMac, tSirQosMapSet* Qos, tDot11fIEQos
tANI_U8 i,j=0;
if (dot11fIE->num_dscp_exceptions > 58)
dot11fIE->num_dscp_exceptions = 58;
+ if (dot11fIE->num_dscp_exceptions < 16)
+ return;
Qos->num_dscp_exceptions = (dot11fIE->num_dscp_exceptions - 16)/2;
for (i=0;i<Qos->num_dscp_exceptions;i++)
{
diff --git a/drivers/staging/prima/CORE/TL/inc/wlan_qct_tl.h b/drivers/staging/prima/CORE/TL/inc/wlan_qct_tl.h
index 35d9f7d976b..45f3b9db2f4 100644
--- a/drivers/staging/prima/CORE/TL/inc/wlan_qct_tl.h
+++ b/drivers/staging/prima/CORE/TL/inc/wlan_qct_tl.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -721,7 +721,16 @@ typedef VOS_STATUS (*WLANTL_STARxCBType)( v_PVOID_t pvosGCtx,
vos_pkt_t* vosDataBuff,
v_U8_t ucSTAId,
WLANTL_RxMetaInfoType* pRxMetaInfo);
-
+/**
+ * WLANTL_FwdEapolCBType() - Call back to forward Eapol packet
+ * @pvosGCtx : pointer to vos global context
+ * @vosDataBuff: pointer to vos packet
+ *
+ * Return: None
+ *
+ */
+typedef void (*WLANTL_FwdEapolCBType) (v_PVOID_t pvosGCtx,
+ vos_pkt_t* vosDataBuff);
/*----------------------------------------------------------------------------
INTERACTION WITH BAP
@@ -3378,6 +3387,39 @@ void WLANTL_ResetRxSSN(v_PVOID_t pvosGCtx, uint8_t ucSTAId);
void WLANTL_SetDataPktFilter(v_PVOID_t pvosGCtx, uint8_t ucSTAId, bool flag);
/**
+ * WLANTL_SampleTx() - collect tx samples
+ * @data: TL context pointer
+ *
+ * This function records the frames fetched from stations
+ * during TX sample interval
+ *
+ * Return: void
+ */
+void WLANTL_SampleTx(void *data);
+
+/*
+ * WLANTL_EnablePreAssocCaching - Enable caching during pre-assoc
+ * @staid: sta client where frames are cached
+ *
+ * Return: none
+ */
+void WLANTL_EnablePreAssocCaching(void);
+
+/*
+ * WLANTL_PreAssocForward - Forward the cached packets
+ *
+ * This function forwards or flushes the packets after
+ * pre assoc success/failure.
+ *
+ * Return: none
+ */
+void WLANTL_PreAssocForward(bool flag);
+
+/* make before break */
+void WLANTL_RegisterFwdEapol(v_PVOID_t pvosGCtx,
+ WLANTL_FwdEapolCBType pfnFwdEapol);
+
+/**
* WLANTL_SetARPFWDatapath() - keep or remove FW in data path for ARP
* @pvosGCtx: global vos context
* @flag: value to keep or remove FW from data path
diff --git a/drivers/staging/prima/CORE/TL/src/wlan_qct_tl.c b/drivers/staging/prima/CORE/TL/src/wlan_qct_tl.c
index 09754b8a967..e5786c036f9 100644..100755
--- a/drivers/staging/prima/CORE/TL/src/wlan_qct_tl.c
+++ b/drivers/staging/prima/CORE/TL/src/wlan_qct_tl.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -243,6 +243,12 @@ int bdPduInterruptGetThreshold = WLANTL_BD_PDU_INTERRUPT_GET_THRESHOLD;
#define ENABLE_ARP_TOGGLE 1
#define SEND_ARP_ON_WQ5 2
+#define WLANTL_RATE_RATIO_THRESHOLD 2
+#define WLANTL_PER_THRESHOLD 5
+#define WLANTL_QUEUE_THRESHOLD 60
+#define WLANTL_GOOD_STA_WEIGHT 1
+#define WLANTL_WEIGHT_THRESHOLD 50
+
/*----------------------------------------------------------------------------
* Type Declarations
* -------------------------------------------------------------------------*/
@@ -692,10 +698,12 @@ WLANTL_Open
}
// scheduling init to be the last one of previous round
- pTLCb->uCurServedAC = WLANTL_AC_BK;
- pTLCb->ucCurLeftWeight = 1;
+ pTLCb->uCurServedAC = WLANTL_AC_VO;
+ pTLCb->ucCurLeftWeight = pTLCb->tlConfigInfo.ucAcWeights[pTLCb->uCurServedAC];
pTLCb->ucCurrentSTA = WLAN_MAX_STA_COUNT-1;
+ vos_timer_init(&pTLCb->tx_frames_timer, VOS_TIMER_TYPE_SW,
+ WLANTL_SampleTx, (void *)pTLCb);
#if 0
//flow control field init
vos_mem_zero(&pTLCb->tlFCInfo, sizeof(tFcTxParams_type));
@@ -833,8 +841,10 @@ WLANTL_Start
/* Enable transmission */
vos_atomic_set_U8( &pTLCb->ucTxSuspended, 0);
-
pTLCb->uResCount = uResCount;
+
+ vos_timer_start(&pTLCb->tx_frames_timer, WLANTL_SAMPLE_INTERVAL);
+
return VOS_STATUS_SUCCESS;
}/* WLANTL_Start */
@@ -917,6 +927,10 @@ WLANTL_Stop
}
#endif
+ if (VOS_TIMER_STATE_STOPPED !=
+ vos_timer_getCurrentState(&pTLCb->tx_frames_timer))
+ vos_timer_stop(&pTLCb->tx_frames_timer);
+
/*-------------------------------------------------------------------------
Clean client stations
-------------------------------------------------------------------------*/
@@ -1011,6 +1025,15 @@ WLANTL_Close
}
#endif
+ if (VOS_TIMER_STATE_RUNNING ==
+ vos_timer_getCurrentState(&pTLCb->tx_frames_timer)) {
+ vos_timer_stop(&pTLCb->tx_frames_timer);
+ }
+ if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(&pTLCb->tx_frames_timer))) {
+ TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+ "%s: Cannot deallocate TX frames sample timer", __func__));
+ }
+
/*------------------------------------------------------------------------
Cleanup TL control block.
------------------------------------------------------------------------*/
@@ -4912,6 +4935,8 @@ WLANTL_GetFrames
pClientSTA->uBuffThresholdMax = (pClientSTA->uBuffThresholdMax >= uResLen) ?
(pClientSTA->uBuffThresholdMax - uResLen) : 0;
+ pClientSTA->tx_frames ++;
+
}
else
{
@@ -5950,6 +5975,153 @@ WLANTL_ProcessFCFrame
return VOS_STATUS_SUCCESS;
}
+/**
+ * WLANTL_FlowControl() - TX Flow control
+ * @pTLCb: TL context pointer
+ * @pvosDataBuff: Firmware indication data buffer
+ *
+ * This function implenets the algorithm to flow control TX traffic in case
+ * of SAP and SAP + STA concurrency.
+ *
+ * Algorithm goal is to fetch more packets from good peer than bad peer by
+ * introducing weights for each station connected. Weight of each station is
+ * calcutated by taking ratio of max RA rate of the peers to its rate. If the
+ * ratio is less than two based on number of queued frames in the station BTQM
+ * weight is modified. If the queued frames reaches the defined threshold weight
+ * is assigned as four. Here weight is inversely proportional to the number of
+ * packets fetch.
+ *
+ * Return true if flow controlled or false otherwise.
+ */
+static bool WLANTL_FlowControl(WLANTL_CbType* pTLCb, vos_pkt_t* pvosDataBuff)
+{
+ WLANTL_FlowControlInfo *fc_data = NULL;
+ WLANTL_PerStaFlowControlParam *sta_fc_params = NULL;
+ uint8_t num_stas;
+ struct sk_buff *skb = NULL;
+ uint16_t data_len;
+ uint8_t *staid;
+ uint16_t max_rate = 0;
+ uint8_t i;
+
+ vos_pkt_get_packet_length(pvosDataBuff, &data_len);
+ if (!data_len) {
+ TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+ "%s: Null fw indication data", __func__));
+ return false;
+ }
+
+ vos_pkt_get_os_packet(pvosDataBuff, (v_VOID_t **)&skb, 0);
+ fc_data = (WLANTL_FlowControlInfo *)skb->data;
+ num_stas = fc_data->num_stas;
+ if (!num_stas) {
+ TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,
+ "%s: No connected stations", __func__));
+ return true;
+ }
+
+ /* Skip flow control for one connected station */
+ if (1 == num_stas)
+ return true;
+
+ staid = (uint8_t *)vos_mem_malloc(WLAN_MAX_STA_COUNT);
+ if (!staid) {
+ TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+ "%s: mem allocation failure", __func__));
+ return false;
+ }
+ vos_mem_set((uint8_t *)staid, WLAN_MAX_STA_COUNT, 0);
+
+ sta_fc_params = (WLANTL_PerStaFlowControlParam *)(&fc_data->num_stas + 1);
+
+ for(i = 0; i < num_stas; i ++, sta_fc_params ++) {
+ staid[i] = sta_fc_params->sta_id;
+
+ if (!pTLCb->atlSTAClients[staid[i]])
+ continue;
+
+ pTLCb->atlSTAClients[staid[i]]->per = sta_fc_params->avg_per;
+ pTLCb->atlSTAClients[staid[i]]->queue = sta_fc_params->queue_len;
+ pTLCb->atlSTAClients[staid[i]]->trate = sta_fc_params->rate;
+ max_rate = max_rate > pTLCb->atlSTAClients[staid[i]]->trate ?
+ max_rate : pTLCb->atlSTAClients[staid[i]]->trate;
+
+ TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
+ "%s: sta_id:%d in:%d queue:%d avg_per:%d rate:%d", __func__,
+ staid[i], pTLCb->atlSTAClients[staid[i]]->tx_samples_sum,
+ pTLCb->atlSTAClients[staid[i]]->queue,
+ pTLCb->atlSTAClients[staid[i]]->per,
+ pTLCb->atlSTAClients[staid[i]]->trate));
+ }
+
+ for (i = 0; i < num_stas; i++) {
+ pTLCb->atlSTAClients[staid[i]]->weight =
+ max_rate/pTLCb->atlSTAClients[staid[i]]->trate;
+ if (pTLCb->atlSTAClients[staid[i]]->weight >=
+ WLANTL_RATE_RATIO_THRESHOLD) {
+ if (!pTLCb->atlSTAClients[staid[i]]->set_flag) {
+ vos_set_hdd_bad_sta(staid[i]);
+ pTLCb->atlSTAClients[staid[i]]->set_flag = true;
+ }
+ /**
+ * If station's link becomes very bad rssi below -90dbm then because
+ * of high PER rate high number of packets are stuck in BTQM which is
+ * affecting the good peers throughput. So throttle further the bad
+ * link traffic.
+ */
+ if ((pTLCb->atlSTAClients[staid[i]]->weight >
+ WLANTL_WEIGHT_THRESHOLD) &&
+ (pTLCb->atlSTAClients[staid[i]]->queue >
+ WLANTL_QUEUE_THRESHOLD))
+ pTLCb->atlSTAClients[staid[i]]->weight *= 2;
+ }
+ if (pTLCb->atlSTAClients[staid[i]]->weight <
+ WLANTL_RATE_RATIO_THRESHOLD) {
+ if (pTLCb->atlSTAClients[staid[i]]->per >= WLANTL_PER_THRESHOLD &&
+ pTLCb->atlSTAClients[staid[i]]->queue > WLANTL_QUEUE_THRESHOLD
+ && !pTLCb->atlSTAClients[staid[i]]->set_flag) {
+ pTLCb->atlSTAClients[staid[i]]->weight *= 2;
+ vos_set_hdd_bad_sta(staid[i]);
+ pTLCb->atlSTAClients[staid[i]]->set_flag = true;
+ }
+ else if (pTLCb->atlSTAClients[staid[i]]->set_flag) {
+ vos_reset_hdd_bad_sta(staid[i]);
+ pTLCb->atlSTAClients[staid[i]]->set_flag = false;
+ }
+ }
+ }
+ vos_mem_free(staid);
+ return true;
+}
+
+/**
+ * WLANTL_CacheEapol() - cache eapol frames
+ * @pTLCb : pointer to TL context
+ * @vosTempBuff: pointer to vos packet buff
+ *
+ * Return: None
+ *
+ */
+static void WLANTL_CacheEapol(WLANTL_CbType* pTLCb, vos_pkt_t* vosTempBuff)
+{
+ if ((NULL == pTLCb) || (NULL == vosTempBuff))
+ {
+ TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+ "%s: Invalid input pointer", __func__));
+ return;
+ }
+
+ if (NULL == pTLCb->vosEapolCachedFrame) {
+ TLLOG1(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,
+ "%s: Cache Eapol frame", __func__));
+ pTLCb->vosEapolCachedFrame = vosTempBuff;
+ }
+ else {
+ TLLOG1(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,
+ "%s: Drop duplicate EAPOL frame", __func__));
+ vos_pkt_return_packet(vosTempBuff);
+ }
+}
/*==========================================================================
@@ -6014,8 +6186,10 @@ WLANTL_RxFrames
#ifdef WLAN_FEATURE_LINK_LAYER_STATS
v_S7_t currentAvgRSSI = 0;
v_U8_t ac;
-
#endif
+ uint8_t ucMPDUHLen;
+ uint16_t seq_no;
+ uint16_t usEtherType = 0;
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
@@ -6053,7 +6227,7 @@ WLANTL_RxFrames
---------------------------------------------------------------------*/
vosTempBuff = vosDataBuff;
- while ( NULL != vosTempBuff )
+ while (NULL != vosDataBuff)
{
broadcast = VOS_FALSE;
selfBcastLoopback = VOS_FALSE;
@@ -6094,7 +6268,8 @@ WLANTL_RxFrames
TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
"WLAN TL:receive one FC frame"));
- WLANTL_ProcessFCFrame(pvosGCtx, vosTempBuff, pvBDHeader);
+ WLANTL_FlowControl(pTLCb, vosTempBuff);
+
/* Drop packet */
vos_pkt_return_packet(vosTempBuff);
vosTempBuff = vosDataBuff;
@@ -6194,6 +6369,9 @@ WLANTL_RxFrames
{
ucSTAId = (v_U8_t)WDA_GET_RX_STAID( pvBDHeader );
ucTid = (v_U8_t)WDA_GET_RX_TID( pvBDHeader );
+ uDPUSig = WDA_GET_RX_DPUSIG(pvBDHeader);
+ ucMPDUHLen = (uint8_t)WDA_GET_RX_MPDU_HEADER_LEN(pvBDHeader);
+ seq_no = (uint16_t)WDA_GET_RX_REORDER_CUR_PKT_SEQ_NO(pvBDHeader);
TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
"WLAN TL:Data packet received for STA %d", ucSTAId));
@@ -6218,6 +6396,28 @@ WLANTL_RxFrames
}
}/*if bcast*/
+ /* Pre assoc cache eapol */
+ if (pTLCb->preassoc_caching)
+ {
+ WLANTL_GetEtherType(pvBDHeader,vosTempBuff, ucMPDUHLen, &usEtherType);
+ if (WLANTL_LLC_8021X_TYPE != usEtherType)
+ {
+ VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,
+ "%s: RX Frame not EAPOL EtherType %d",
+ __func__, usEtherType);
+ vos_pkt_return_packet(vosTempBuff);
+ }
+ else
+ {
+ WLANTL_CacheEapol(pTLCb, vosTempBuff);
+ TLLOG1(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,
+ "WLAN TL:TL preassoc_caching is enabled seq No: %d", seq_no));
+ }
+
+ vosTempBuff = vosDataBuff;
+ continue;
+ }
+
if (WLANTL_STA_ID_INVALID(ucSTAId))
{
TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN,
@@ -6328,8 +6528,7 @@ WLANTL_RxFrames
vosTempBuff = vosDataBuff;
continue;
}
- uDPUSig = WDA_GET_RX_DPUSIG( pvBDHeader );
- //Station has not yet been registered with TL - cache the frame
+ /* Station has not yet been registered with TL - cache the frame */
TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN,
"%s: staId %d exist %d tlState %d cache rx frame", __func__, ucSTAId,
pClientSTA->ucExists, pClientSTA->tlState));
@@ -6941,6 +7140,47 @@ WLANTL_RxCachedFrames
return VOS_STATUS_SUCCESS;
}/* WLANTL_RxCachedFrames */
+/**
+ * WLANTL_ForwardPkts() - forward cached eapol frames
+ * @pvosGCtx: pointer to vos global context
+ * @data: value to indicate either forward or flush
+ *
+ * Return: None
+ *
+ */
+static VOS_STATUS WLANTL_ForwardPkts(void* pvosGCtx, uint32_t data)
+{
+ WLANTL_CbType* pTLCb = NULL;
+
+ pTLCb = VOS_GET_TL_CB(pvosGCtx);
+ if (NULL == pTLCb) {
+ TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+ "%s: Invalid input pointer", __func__));
+ return VOS_STATUS_E_FAULT;
+ }
+
+ if (!data) {
+ TLLOG2(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
+ "%s: Pre assoc fail flush cache", __func__));
+ WLANTL_FlushCachedFrames(pTLCb->vosEapolCachedFrame);
+ goto done;
+ }
+
+ /* forward packets to HDD */
+ if (NULL != pTLCb->vosEapolCachedFrame) {
+ TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
+ "%s: forward pre assoc cached frames", __func__));
+ WLANTL_MonTranslate80211To8023Header(pTLCb->vosEapolCachedFrame, pTLCb);
+ pTLCb->pfnEapolFwd(pvosGCtx, pTLCb->vosEapolCachedFrame);
+ }
+
+done:
+ pTLCb->vosEapolCachedFrame = NULL;
+ pTLCb->preassoc_caching = false;
+
+ return VOS_STATUS_SUCCESS;
+}
+
/*==========================================================================
FUNCTION WLANTL_RxProcessMsg
@@ -7018,6 +7258,11 @@ WLANTL_RxProcessMsg
ucUcastSig, ucBcastSig);
break;
+ case WLANTL_RX_FWD_PRE_ASSOC_CACHED:
+ uData = message->bodyval;
+ vosStatus = WLANTL_ForwardPkts(pvosGCtx, uData);
+ break;
+
default:
/*no processing for now*/
break;
@@ -8309,13 +8554,11 @@ WLANTL_STATxAuth
{
if (pTLCb->track_arp)
{
- if (vos_check_arp_req_target_ip(vosDataBuff->pSkb, true))
+ if (vos_check_arp_target_ip(vosDataBuff))
{
ucTxFlag |= HAL_USE_FW_IN_TX_PATH;
ucTxFlag |= HAL_TXCOMP_REQUESTED_MASK;
tlMetaInfo.ucTxBdToken = ++ pTLCb->txbd_token;
- TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,
- "%s: ARP packet FW in data path", __func__));
}
}
@@ -11428,12 +11671,15 @@ WLAN_TLAPGetNextTxIds
{
WLANTL_CbType* pTLCb;
v_U8_t ucACFilter = 1;
- v_U8_t ucNextSTA ;
+ v_U8_t ucNextSTA, ucTempSTA;
v_BOOL_t isServed = TRUE; //current round has find a packet or not
v_U8_t ucACLoopNum = WLANTL_AC_HIGH_PRIO + 1; //number of loop to go
v_U8_t uFlowMask; // TX FlowMask from WDA
uint8 ucACMask;
- uint8 i = 0;
+ uint8 i = 0;
+ uint8 j;
+ uint8 minWeightSta;
+ uint32_t sta_bitmask = 0;
/*------------------------------------------------------------------------
Extract TL control block
------------------------------------------------------------------------*/
@@ -11475,10 +11721,8 @@ WLAN_TLAPGetNextTxIds
++ucNextSTA;
if ( WLAN_MAX_STA_COUNT <= ucNextSTA )
- {
- //one round is done.
ucNextSTA = 0;
- pTLCb->ucCurLeftWeight--;
+
isServed = FALSE;
if ( 0 == pTLCb->ucCurLeftWeight )
{
@@ -11496,7 +11740,9 @@ WLAN_TLAPGetNextTxIds
pTLCb->ucCurLeftWeight = pTLCb->tlConfigInfo.ucAcWeights[pTLCb->uCurServedAC];
} // (0 == pTLCb->ucCurLeftWeight)
- } //( WLAN_MAX_STA_COUNT == ucNextSTA )
+
+ ucTempSTA = ucNextSTA;
+ minWeightSta = ucNextSTA;
//decide how many loops to go. if current loop is partial, do one extra to make sure
//we cover every station
@@ -11554,6 +11800,30 @@ WLAN_TLAPGetNextTxIds
continue;
}
+ /*
+ * Initial weight is 0 is for all the stations. As part of FW TX stats
+ * indication to host, good peer weight is updated to one and the
+ * remaining peers weight is updated based on their RA rates and BTQM
+ * queued frames length. TL skips fetching the packet until the station
+ * has got chances equal to its weight.
+ */
+ if (pTLCb->atlSTAClients[ucNextSTA]->weight > WLANTL_GOOD_STA_WEIGHT) {
+ if (pTLCb->atlSTAClients[ucNextSTA]->weight_count <=
+ pTLCb->atlSTAClients[ucNextSTA]->weight)
+ {
+ if (pTLCb->atlSTAClients[minWeightSta]->weight <= 1)
+ minWeightSta = ucNextSTA;
+ else if (pTLCb->atlSTAClients[ucNextSTA]->weight <
+ pTLCb->atlSTAClients[minWeightSta]->weight) {
+ minWeightSta = ucNextSTA;
+ }
+ sta_bitmask |= (1 << ucNextSTA);
+ pTLCb->atlSTAClients[ucNextSTA]->weight_count++;
+ continue;
+ }
+ else
+ pTLCb->atlSTAClients[ucNextSTA]->weight_count = 0;
+ }
// Find a station. Weight is updated already.
*pucSTAId = ucNextSTA;
@@ -11564,9 +11834,92 @@ WLAN_TLAPGetNextTxIds
" TL serve one station AC: %d W: %d StaId: %d",
pTLCb->uCurServedAC, pTLCb->ucCurLeftWeight, pTLCb->ucCurrentSTA ));
+ pTLCb->ucCurLeftWeight--;
return VOS_STATUS_SUCCESS;
} //STA loop
+ for (j = 0; j < ucTempSTA; j++) {
+ if (NULL == pTLCb->atlSTAClients[j])
+ continue;
+
+ WLAN_TL_AC_ARRAY_2_MASK (pTLCb->atlSTAClients[j], ucACMask, i);
+
+ if ((0 == pTLCb->atlSTAClients[j]->ucExists) ||
+ ((0 == pTLCb->atlSTAClients[j]->ucPktPending) && !(ucACMask)) ||
+ (0 == (ucACMask & ucACFilter)))
+ continue;
+
+ if ((WLANTL_STA_AUTHENTICATED != pTLCb->atlSTAClients[j]->tlState) ||
+ (pTLCb->atlSTAClients[j]->disassoc_progress == VOS_TRUE)) {
+ TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
+ "%s Sta %d not in auth state so skipping it.",
+ __func__, ucNextSTA));
+ continue;
+ }
+
+ if ((TRUE == pTLCb->atlSTAClients[j]->ucLwmModeEnabled) &&
+ ((FALSE == pTLCb->atlSTAClients[j]->ucLwmEventReported) ||
+ (0 < pTLCb->atlSTAClients[j]->uBuffThresholdMax)))
+ continue;
+
+ if (pTLCb->atlSTAClients[j]->weight > WLANTL_GOOD_STA_WEIGHT) {
+ if (pTLCb->atlSTAClients[j]->weight_count <=
+ pTLCb->atlSTAClients[j]->weight)
+ {
+ if (pTLCb->atlSTAClients[minWeightSta]->weight <= 1)
+ minWeightSta = j;
+ else if (pTLCb->atlSTAClients[j]->weight <
+ pTLCb->atlSTAClients[minWeightSta]->weight) {
+ minWeightSta = j;
+ }
+ sta_bitmask |= (1 << j);
+ pTLCb->atlSTAClients[j]->weight_count++;
+ continue;
+ }
+ else
+ pTLCb->atlSTAClients[j]->weight_count = 0;
+ }
+
+ *pucSTAId = j;
+ pTLCb->ucCurrentSTA = j;
+ pTLCb->atlSTAClients[*pucSTAId]->ucCurrentAC = pTLCb->uCurServedAC;
+
+ TLLOG4(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,
+ " TL serve one station AC: %d W: %d StaId: %d",
+ pTLCb->uCurServedAC, pTLCb->ucCurLeftWeight, pTLCb->ucCurrentSTA ));
+ pTLCb->ucCurLeftWeight--;
+ return VOS_STATUS_SUCCESS;
+ }
+
+ /* Fecth packet from the stations with minimum weight among them */
+ if (pTLCb->atlSTAClients[minWeightSta] &&
+ pTLCb->atlSTAClients[minWeightSta]->ucPktPending)
+ {
+ *pucSTAId = minWeightSta;
+ pTLCb->ucCurrentSTA = minWeightSta;
+ pTLCb->atlSTAClients[*pucSTAId]->ucCurrentAC = pTLCb->uCurServedAC;
+
+ for (j = 0; sta_bitmask != 0; sta_bitmask >>= 1, j++)
+ {
+ if (0 == (sta_bitmask & 0x1))
+ continue;
+
+ if (minWeightSta == j)
+ continue;
+ /* To ensure fairness between stations */
+ pTLCb->atlSTAClients[j]->weight_count +=
+ pTLCb->atlSTAClients[minWeightSta]->weight -
+ pTLCb->atlSTAClients[minWeightSta]->weight_count;
+ }
+ pTLCb->atlSTAClients[minWeightSta]->weight_count = 0;
+
+ TLLOG4(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,
+ " TL serve one station AC: %d W: %d StaId: %d",
+ pTLCb->uCurServedAC, pTLCb->ucCurLeftWeight, pTLCb->ucCurrentSTA ));
+ pTLCb->ucCurLeftWeight--;
+ return VOS_STATUS_SUCCESS;
+ }
+
ucNextSTA = 0;
if ( FALSE == isServed )
{
@@ -11722,6 +12075,18 @@ WLAN_TLGetNextTxIds
{
continue;
}
+
+ if ((pTLCb->atlSTAClients[ucNextSTA]->weight > WLANTL_GOOD_STA_WEIGHT) &&
+ (pTLCb->atlSTAClients[ucNextSTA]->ucPktPending)) {
+ if (pTLCb->atlSTAClients[ucNextSTA]->weight_count <=
+ pTLCb->atlSTAClients[ucNextSTA]->weight) {
+ pTLCb->atlSTAClients[ucNextSTA]->weight_count++;
+ continue;
+ }
+ else
+ pTLCb->atlSTAClients[ucNextSTA]->weight_count = 0;
+ }
+
if (( pTLCb->atlSTAClients[ucNextSTA]->ucExists ) &&
( pTLCb->atlSTAClients[ucNextSTA]->ucPktPending ))
{
@@ -13828,7 +14193,169 @@ void WLANTL_ResetRxSSN(v_PVOID_t pvosGCtx, uint8_t ucSTAId)
}
}
+void WLANTL_SetDataPktFilter(v_PVOID_t pvosGCtx, uint8_t ucSTAId, bool flag)
+{
+ WLANTL_CbType* pTLCb = NULL;
+ WLANTL_STAClientType* pClientSTA = NULL;
+ uint8_t i;
+
+ if (WLANTL_STA_ID_INVALID(ucSTAId)) {
+ TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+ "%s: Invalid station id requested", __func__));
+ return;
+ }
+
+ pTLCb = VOS_GET_TL_CB(pvosGCtx);
+ if (NULL == pTLCb) {
+ TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+ "%s: Invalid TL pointer from pvosGCtx", __func__));
+ return;
+ }
+
+ pClientSTA = pTLCb->atlSTAClients[ucSTAId];
+
+ for (i = 0; i < WLAN_MAX_TID ; i++) {
+ if (0 == pClientSTA->atlBAReorderInfo[i].ucExists)
+ continue;
+
+ TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,
+ "WLAN TL: Last RxSSN reset to zero for tid %d", i));
+ pClientSTA->atlBAReorderInfo[i].set_data_filter = flag;
+ }
+}
+
+/**
+ * WLANTL_ShiftArrByOne() - utility function to shift array by one
+ * @arr: pointer to array
+ * @len: length of the array
+ *
+ * Caller responsibility to provide the correct length of the array
+ * other may leads to bugs.
+ *
+ * Return: void
+ */
+static void WLANTL_ShiftArrByOne(uint32_t *arr, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len - 1; i ++)
+ arr[i] = arr[i + 1];
+ arr[i] = 0;
+}
+
+/**
+ * WLANTL_SampleTx() - collect tx samples
+ * @data: TL context pointer
+ *
+ * This function records the last five tx bytes sent samples
+ * collected after tx_bytes_timer expire.
+ *
+ * Return: void
+ */
+void WLANTL_SampleTx(void *data)
+{
+ WLANTL_CbType* pTLCb = (WLANTL_CbType *)data;
+ WLANTL_STAClientType* pClientSTA = NULL;
+ uint8_t count = pTLCb->sample_count;
+ uint8_t i;
+
+ for ( i = 0; i < WLAN_MAX_STA_COUNT; i++) {
+ if (NULL != pTLCb->atlSTAClients[i] &&
+ pTLCb->atlSTAClients[i]->ucExists) {
+ pClientSTA = pTLCb->atlSTAClients[i];
+
+ if (count > (WLANTL_SAMPLE_COUNT - 1)) {
+ count = WLANTL_SAMPLE_COUNT - 1;
+ pClientSTA->tx_samples_sum -= pClientSTA->tx_sample[0];
+ WLANTL_ShiftArrByOne(pClientSTA->tx_sample, WLANTL_SAMPLE_COUNT);
+ }
+
+ pClientSTA->tx_sample[count] = pClientSTA->tx_frames;
+ pClientSTA->tx_samples_sum += pClientSTA->tx_sample[count];
+ pClientSTA->tx_frames = 0;
+ count++;
+ pTLCb->sample_count = count;
+ }
+ }
+
+ vos_timer_start(&pTLCb->tx_frames_timer, WLANTL_SAMPLE_INTERVAL);
+}
+
/**
+ * WLANTL_EnablePreAssocCaching() - Enable caching EAPOL frames
+ *
+ * Return: None
+ *
+ */
+void WLANTL_EnablePreAssocCaching(void)
+{
+ v_PVOID_t pvosGCtx= vos_get_global_context(VOS_MODULE_ID_TL,NULL);
+ WLANTL_CbType* pTLCb = VOS_GET_TL_CB(pvosGCtx);
+ if (NULL == pTLCb ) {
+ TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+ "%s: Invalid TL pointer for global context", __func__));
+ return;
+ }
+
+ pTLCb->vosEapolCachedFrame = NULL;
+ pTLCb->preassoc_caching = true;
+}
+
+/**
+ * WLANTL_ForwardPreAssoc() - forward cached eapol frames
+ * @flag: Value to forward or flush
+ *
+ * Return: vos status
+ *
+ */
+static VOS_STATUS WLANTL_ForwardPreAssoc(bool flag)
+{
+ vos_msg_t sMessage;
+
+ VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+ " ---- Serializing TL for forwarding pre assoc cache frames");
+
+ vos_mem_zero( &sMessage, sizeof(vos_msg_t));
+ sMessage.type = WLANTL_RX_FWD_PRE_ASSOC_CACHED;
+ sMessage.bodyval = flag;
+
+ return vos_rx_mq_serialize(VOS_MQ_ID_TL, &sMessage);
+}
+
+/**
+ * WLANTL_PreAssocForward() - forward cached eapol frames
+ * @flag: Value to forward or flush
+ *
+ * Return: None
+ *
+ */
+void WLANTL_PreAssocForward(bool flag)
+{
+ if(!VOS_IS_STATUS_SUCCESS(WLANTL_ForwardPreAssoc(flag)))
+ {
+ VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+ " %s fails to forward packets", __func__);
+ }
+}
+
+/**
+ * WLANTL_RegisterFwdEapol() - register call back to forward cached eapol frame
+ * @pvosGCtx : pointer to vos global context
+ * @pfnFwdEapol: call back function pointer
+ *
+ * Return: None
+ *
+ */
+void WLANTL_RegisterFwdEapol(v_PVOID_t pvosGCtx,
+ WLANTL_FwdEapolCBType pfnFwdEapol)
+{
+ WLANTL_CbType* pTLCb = NULL;
+ pTLCb = VOS_GET_TL_CB(pvosGCtx);
+
+ pTLCb->pfnEapolFwd = pfnFwdEapol;
+
+}
+
+ /**
* WLANTL_SetARPFWDatapath() - keep or remove FW in data path for ARP
*
* @flag: value to keep or remove FW from data path
@@ -14464,34 +14991,3 @@ WLANTL_SetMcastDuplicateDetection
}
#endif /* WLAN_FEATURE_RMC */
-
-void WLANTL_SetDataPktFilter(v_PVOID_t pvosGCtx, uint8_t ucSTAId, bool flag)
-{
- WLANTL_CbType* pTLCb = NULL;
- WLANTL_STAClientType* pClientSTA = NULL;
- uint8_t i;
-
- if (WLANTL_STA_ID_INVALID(ucSTAId)) {
- TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
- "%s: Invalid station id requested", __func__));
- return;
- }
-
- pTLCb = VOS_GET_TL_CB(pvosGCtx);
- if (NULL == pTLCb) {
- TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
- "%s: Invalid TL pointer from pvosGCtx", __func__));
- return;
- }
-
- pClientSTA = pTLCb->atlSTAClients[ucSTAId];
-
- for (i = 0; i < WLAN_MAX_TID ; i++) {
- if (0 == pClientSTA->atlBAReorderInfo[i].ucExists)
- continue;
-
- TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,
- "WLAN TL: Last RxSSN reset to zero for tid %d", i));
- pClientSTA->atlBAReorderInfo[i].set_data_filter = flag;
- }
-}
diff --git a/drivers/staging/prima/CORE/TL/src/wlan_qct_tl_ba.c b/drivers/staging/prima/CORE/TL/src/wlan_qct_tl_ba.c
index ccfcfb0c699..b97af6cfdf1 100644
--- a/drivers/staging/prima/CORE/TL/src/wlan_qct_tl_ba.c
+++ b/drivers/staging/prima/CORE/TL/src/wlan_qct_tl_ba.c
@@ -1166,10 +1166,7 @@ VOS_STATUS WLANTL_MSDUReorder
"(QCUR_FWDBUF) dropping old frame, SN=%d LastSN=%d",
CSN, currentReorderInfo->LastSN));
if (vos_is_arp_pkt((*vosDataBuff)->pSkb, true))
- {
- if (vos_check_arp_rsp_src_ip((*vosDataBuff)->pSkb, true))
- vos_update_arp_rx_drop_reorder();
- }
+ vos_update_arp_rx_drop_reorder();
status = vos_pkt_return_packet(*vosDataBuff);
if (!VOS_IS_STATUS_SUCCESS(status))
diff --git a/drivers/staging/prima/CORE/TL/src/wlan_qct_tli.h b/drivers/staging/prima/CORE/TL/src/wlan_qct_tli.h
index fdb5898b8fb..cb6414a6143 100644
--- a/drivers/staging/prima/CORE/TL/src/wlan_qct_tli.h
+++ b/drivers/staging/prima/CORE/TL/src/wlan_qct_tli.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -190,6 +190,9 @@ when who what, where, why
#define WLANTL_RMC_HASH_TABLE_SIZE (32)
#endif
+#define WLANTL_SAMPLE_INTERVAL 50
+#define WLANTL_SAMPLE_COUNT 2
+
/*-------------------------------------------------------------------------
BT-AMP related definition - !!! should probably be moved to BT-AMP header
---------------------------------------------------------------------------*/
@@ -302,6 +305,8 @@ typedef enum
/* Forwarding RX cached frames */
WLANTL_RX_FWD_CACHED = 0,
+ /* Forward pre assoc cached frames */
+ WLANTL_RX_FWD_PRE_ASSOC_CACHED = 1,
}WLANTL_RxSignalsType;
/*---------------------------------------------------------------------------
@@ -727,6 +732,20 @@ typedef struct
/* Disassoc in progress */
v_BOOL_t disassoc_progress;
+
+ /* sample timer Tx frames */
+ uint64_t tx_frames;
+ uint32_t tx_sample[WLANTL_SAMPLE_COUNT];
+ uint64_t tx_samples_sum;
+
+ /* flow control */
+ uint8_t weight;
+ uint8_t weight_count;
+ uint8_t per;
+ uint8_t set_flag;
+ uint16_t queue;
+ uint16_t trate;
+
}WLANTL_STAClientType;
/*---------------------------------------------------------------------------
@@ -811,6 +830,19 @@ typedef struct
vos_lock_t hosLock;
} WLANTL_HO_SUPPORT_TYPE;
+typedef struct {
+ uint8 sta_id;
+ uint8 avg_per;
+ uint16 queue_len;
+ uint16_t rate;
+ uint16_t reserved;
+} WLANTL_PerStaFlowControlParam;
+
+typedef struct {
+ uint8 num_stas;
+ WLANTL_PerStaFlowControlParam *sta_fc_info;
+} WLANTL_FlowControlInfo;
+
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
#define ROAM_MAX_INDEX_NUM 50
#define ROAM_PER_INDEX_TIME 500 /* (msec) */
@@ -967,8 +999,17 @@ typedef struct
WLANTL_RoamMonitorType gDsRxRoamStats;
#endif
+ /* TX sample data timer */
+ vos_timer_t tx_frames_timer;
+ uint8_t sample_count;
+
+ bool preassoc_caching;
+ vos_pkt_t* vosEapolCachedFrame;
+ WLANTL_FwdEapolCBType pfnEapolFwd;
+
uint8_t track_arp;
uint32_t txbd_token;
+
}WLANTL_CbType;
diff --git a/drivers/staging/prima/CORE/VOSS/inc/event_defs.h b/drivers/staging/prima/CORE/VOSS/inc/event_defs.h
index 690745667e7..869017202a4 100644
--- a/drivers/staging/prima/CORE/VOSS/inc/event_defs.h
+++ b/drivers/staging/prima/CORE/VOSS/inc/event_defs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -1911,6 +1911,8 @@ typedef enum
EVENT_OFFLOAD_REQ = 0xAB8,
EVENT_TDLS_SCAN_BLOCK = 0xAB9,
EVENT_WLAN_TX_RX_MGMT = 0xABA,
+ EVENT_WLAN_SSR_REINIT_SUBSYSTEM = 0xB3C,
+ EVENT_WLAN_SSR_SHUTDOWN_SUBSYSTEM = 0xB3D,
EVENT_NEXT_UNUSED_EVENT,
EVENT_RSVD_START = 0x0800,
EVENT_RSVD_END = 0x083F,
diff --git a/drivers/staging/prima/CORE/VOSS/inc/vos_api.h b/drivers/staging/prima/CORE/VOSS/inc/vos_api.h
index 4e5882db702..5c7fd8c0e7c 100644
--- a/drivers/staging/prima/CORE/VOSS/inc/vos_api.h
+++ b/drivers/staging/prima/CORE/VOSS/inc/vos_api.h
@@ -517,21 +517,21 @@ v_BOOL_t vos_isLoadUnloadInProgress(void);
bool vos_get_rx_wow_dump(void);
void vos_set_rx_wow_dump(bool value);
+void vos_set_hdd_bad_sta(uint8_t sta_id);
+void vos_reset_hdd_bad_sta(uint8_t sta_id);
+
void vos_probe_threads(void);
void vos_per_pkt_stats_to_user(void *perPktStat);
void vos_updatePktStatsInfo(void * pktStat);
bool vos_is_wlan_logging_enabled(void);
v_BOOL_t vos_is_probe_rsp_offload_enabled(void);
+void vos_set_snoc_high_freq_voting(bool enable);
void vos_smd_dump_stats(void);
void vos_log_wdi_event(uint16 msg, vos_wdi_trace_event_type event);
void vos_dump_wdi_events(void);
-bool vos_check_arp_target_ip(void *pSkb, bool conversion);
-bool vos_check_arp_req_target_ip(void *pSkb, bool conversion);
-bool vos_check_arp_src_ip(void *pSkb, bool conversion);
-bool vos_check_arp_rsp_src_ip(void *pSkb, bool conversion);
+bool vos_check_arp_target_ip(vos_pkt_t *pPacket);
void vos_update_arp_fw_tx_delivered(void);
void vos_update_arp_rx_drop_reorder(void);
-void vos_set_snoc_high_freq_voting(bool enable);
#endif // if !defined __VOS_NVITEM_H
diff --git a/drivers/staging/prima/CORE/VOSS/inc/vos_diag_core_event.h b/drivers/staging/prima/CORE/VOSS/inc/vos_diag_core_event.h
index c52a6f56033..ac7b39b2aea 100644
--- a/drivers/staging/prima/CORE/VOSS/inc/vos_diag_core_event.h
+++ b/drivers/staging/prima/CORE/VOSS/inc/vos_diag_core_event.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -385,6 +385,47 @@ struct vos_event_wlan_log_complete {
uint32_t reserved;
};
+/*-------------------------------------------------------------------------
+ Event ID: EVENT_WLAN_SSR_REINIT_SUBSYSTEM
+ ------------------------------------------------------------------------*/
+/**
+ * struct host_event_wlan_css - Holds diag event details
+ * @status: Indicates the status of event
+ *
+ * This structure holds the host diag event related information
+ */
+
+struct host_event_wlan_ssr_reinit {
+ uint32_t status;
+};
+
+/*-------------------------------------------------------------------------
+ Event ID: EVENT_WLAN_SSR_SHUTDOWN_SUBSYSTEM
+ ------------------------------------------------------------------------*/
+/**
+ * struct host_event_wlan_ssr_shutdown - Holds diag event details
+ * @status: Indicates the status of event
+ *
+ * This structure holds the host diag event related information
+ */
+
+struct host_event_wlan_ssr_shutdown {
+ uint32_t status;
+};
+
+/*-------------------------------------------------------------------------
+ Function declarations and documenation
+ ------------------------------------------------------------------------*/
+/**
+ * enum host_ssr_events - Enum containing ssr subtype
+ * @SSR_SUB_SYSTEM_REINIT: Indicate ssr reinit state
+ * @SSR_SUB_SYSTEM_SHUTDOWN: Indicate ssr shutdown state
+ *
+ */
+enum host_ssr_events {
+ SSR_SUB_SYSTEM_REINIT,
+ SSR_SUB_SYSTEM_SHUTDOWN,
+};
/*-------------------------------------------------------------------------
Function declarations and documenation
@@ -413,6 +454,7 @@ enum wake_lock_reason {
WIFI_POWER_EVENT_WAKELOCK_ROC,
WIFI_POWER_EVENT_WAKELOCK_HOLD_RX,
WIFI_POWER_EVENT_WAKELOCK_SAP,
+ WIFI_POWER_EVENT_WAKELOCK_FIND_AP_INDICATION,
};
#ifdef __cplusplus
diff --git a/drivers/staging/prima/CORE/VOSS/inc/vos_packet.h b/drivers/staging/prima/CORE/VOSS/inc/vos_packet.h
index 06e8e2c9ef2..ad838d7bcf9 100644
--- a/drivers/staging/prima/CORE/VOSS/inc/vos_packet.h
+++ b/drivers/staging/prima/CORE/VOSS/inc/vos_packet.h
@@ -53,16 +53,6 @@
#define VOS_PKT_PROTO_TYPE_EAPOL 0x02
#define VOS_PKT_PROTO_TYPE_DHCP 0x04
#define VOS_PKT_PROTO_TYPE_ARP 0x08
-
-/* ARP packet offset values */
-#define VOS_PKT_ARP_OPCODE_OFFSET 20
-#define VOS_PKT_ARPOP_REQUEST 1
-#define VOS_PKT_ARPOP_REPLY 2
-#define VOS_ARP_TARGET_IP_OFFSET 38
-#define VOS_ARP_SRC_IP_OFFSET 28
-
-#define VOS_80211_8023_HEADER_OFFSET 20
-
/*--------------------------------------------------------------------------
Type declarations
------------------------------------------------------------------------*/
diff --git a/drivers/staging/prima/CORE/VOSS/inc/vos_timer.h b/drivers/staging/prima/CORE/VOSS/inc/vos_timer.h
index 70a09772169..12e2f7cc13c 100644
--- a/drivers/staging/prima/CORE/VOSS/inc/vos_timer.h
+++ b/drivers/staging/prima/CORE/VOSS/inc/vos_timer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -326,6 +326,20 @@ VOS_STATUS vos_timer_stop( vos_timer_t *timer );
------------------------------------------------------------------------*/
v_TIME_t vos_timer_get_system_ticks( v_VOID_t );
+/**
+ * vos_system_time_after() - Check if a is later than b
+ * @a: Time stamp value a
+ * @b: Time stamp value b
+ *
+ * Return:
+ * true if a is after b else false
+ */
+static inline bool vos_system_time_after(v_TIME_t a, v_TIME_t b)
+{
+ return (long)(b) - (long)(a) < 0;
+}
+
+
/*--------------------------------------------------------------------------
diff --git a/drivers/staging/prima/CORE/VOSS/src/vos_api.c b/drivers/staging/prima/CORE/VOSS/src/vos_api.c
index bfff2cc16d7..8e048bad193 100644
--- a/drivers/staging/prima/CORE/VOSS/src/vos_api.c
+++ b/drivers/staging/prima/CORE/VOSS/src/vos_api.c
@@ -103,6 +103,9 @@
/* Trace index for WDI Read/Write */
#define VOS_TRACE_INDEX_MAX 256
+/* ARP Target IP offset */
+#define VOS_ARP_TARGET_IP_OFFSET 58
+
/*---------------------------------------------------------------------------
* Data definitions
* ------------------------------------------------------------------------*/
@@ -1848,7 +1851,7 @@ VOS_STATUS __vos_fatal_event_logs_req( uint32_t is_fatal,
return VOS_STATUS_E_FAILURE;
}
- if(!pHddCtx->cfg_ini->enableFatalEvent)
+ if (!pHddCtx->cfg_ini->enableFatalEvent || !pHddCtx->is_fatal_event_log_sup)
{
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
"%s: Fatal event not enabled", __func__);
@@ -3287,6 +3290,59 @@ void vos_set_rx_wow_dump(bool value)
}
/**
+ * vos_set_hdd_bad_sta() - Set bad link peer sta id
+ * @sta_id: sta id of the bad peer
+ *
+ * Return none.
+ */
+void vos_set_hdd_bad_sta(uint8_t sta_id)
+{
+ hdd_context_t *pHddCtx = NULL;
+ v_CONTEXT_t pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
+
+ if(!pVosContext)
+ {
+ hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
+ return;
+ }
+
+ pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
+ if(!pHddCtx) {
+ VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
+ "%s: HDD context is Null", __func__);
+ return;
+ }
+
+ pHddCtx->bad_sta[sta_id] = 1;
+}
+
+/**
+ * vos_reset_hdd_bad_sta() - Reset the bad peer sta_id
+ * @sta_id: sta id of the peer
+ *
+ * Return none.
+ */
+void vos_reset_hdd_bad_sta(uint8_t sta_id)
+{
+ hdd_context_t *pHddCtx = NULL;
+ v_CONTEXT_t pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
+
+ if(!pVosContext) {
+ hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
+ return;
+ }
+
+ pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
+ if(!pHddCtx) {
+ VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
+ "%s: HDD context is Null", __func__);
+ return;
+ }
+
+ pHddCtx->bad_sta[sta_id] = 0;
+}
+
+/**
* vos_probe_threads() - VOS API to post messages
* to all the threads to detect if they are active or not
*
@@ -3632,6 +3688,46 @@ v_BOOL_t vos_is_probe_rsp_offload_enabled(void)
return pHddCtx->cfg_ini->sap_probe_resp_offload;
}
+
+/**
+ * vos_set_snoc_high_freq_voting() - enable/disable high freq voting
+ * @enable: true if need to be enabled
+ *
+ * enable/disable high freq voting
+ *
+ * Return: Void
+ */
+#ifdef HAVE_WCNSS_SNOC_HIGH_FREQ_VOTING
+void vos_set_snoc_high_freq_voting(bool enable)
+{
+ VosContextType *vos_ctx = NULL;
+
+ /* Get the Global VOSS Context */
+ vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
+
+ if (!vos_ctx) {
+ VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+ "%s: vos context is NULL", __func__);
+ return;
+ }
+
+ spin_lock(&vos_ctx->freq_voting_lock);
+ if (vos_ctx->snoc_high_freq_voting != enable)
+ {
+ vos_ctx->snoc_high_freq_voting = enable;
+ spin_unlock(&vos_ctx->freq_voting_lock);
+ wcnss_snoc_vote(enable);
+ return;
+ }
+ spin_unlock(&vos_ctx->freq_voting_lock);
+}
+#else
+void vos_set_snoc_high_freq_voting(bool enable)
+{
+ return;
+}
+#endif
+
void vos_smd_dump_stats(void)
{
WCTS_Dump_Smd_status();
@@ -3666,19 +3762,18 @@ void vos_dump_wdi_events(void)
gvos_wdi_msg_trace[i].message);
}
}
+
/**
* vos_check_arp_target_ip() - check if the Target IP is gateway IP
* @pPacket: pointer to vos packet
- * @conversion: 802.3 to 802.11 frame conversion
*
* Return: true if the IP is of gateway or false otherwise
*/
-bool vos_check_arp_target_ip(void *pSkb, bool conversion)
+bool vos_check_arp_target_ip(vos_pkt_t *pPacket)
{
v_CONTEXT_t pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
hdd_context_t *pHddCtx = NULL;
struct sk_buff *skb;
- uint8_t offset;
if(!pVosContext)
{
@@ -3693,164 +3788,29 @@ bool vos_check_arp_target_ip(void *pSkb, bool conversion)
return false;
}
- if (unlikely(NULL == pSkb))
- {
- VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
- "%s: NULL pointer", __func__);
- return false;
- }
-
- skb = (struct sk_buff *)pSkb;
-
- if (conversion)
- offset = VOS_ARP_TARGET_IP_OFFSET + VOS_80211_8023_HEADER_OFFSET;
- else
- offset = VOS_ARP_TARGET_IP_OFFSET;
-
- if (pHddCtx->track_arp_ip ==
- (v_U32_t)(*(v_U32_t *)(skb->data + offset)))
- return true;
-
- return false;
-}
-
-/**
- * vos_check_arp_req_target_ip() - check if the ARP is request and
- target IP is gateway
- * @pPacket: pointer to vos packet
- * @conversion: 802.3 to 802.11 frame conversion
- *
- * Return: true if the IP is of gateway or false otherwise
- */
-bool vos_check_arp_req_target_ip(void *pSkb, bool conversion)
-{
- v_CONTEXT_t pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
- struct sk_buff *skb;
- uint8_t offset;
-
- if(!pVosContext)
- {
- hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
- return false;
- }
-
- if (unlikely(NULL == pSkb))
+ if (unlikely(NULL == pPacket))
{
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
"%s: NULL pointer", __func__);
return false;
}
- skb = (struct sk_buff *)pSkb;
-
- if (conversion)
- offset = VOS_PKT_ARP_OPCODE_OFFSET + VOS_80211_8023_HEADER_OFFSET;
- else
- offset = VOS_PKT_ARP_OPCODE_OFFSET;
-
- if (htons(VOS_PKT_ARPOP_REQUEST) ==
- (uint16_t)(*(uint16_t *)(skb->data + offset)))
- {
- if (vos_check_arp_target_ip(skb, conversion))
- return true;
- }
-
- return false;
-}
-
-/**
- * vos_check_arp_src_ip() - check if the ARP response src IP is gateway IP
- * @pPacket: pointer to vos packet
- * @conversion: 802.3 to 802.11 frame conversion
- *
- * Return: true if the IP is of gateway or false otherwise
- */
-bool vos_check_arp_src_ip(void *pSkb, bool conversion)
-{
- v_CONTEXT_t pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
- hdd_context_t *pHddCtx = NULL;
- struct sk_buff *skb;
- uint8_t offset;
-
- if(!pVosContext)
- {
- hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
- return false;
- }
-
- pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
- if(!pHddCtx) {
- VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
- "%s: HDD context is Null", __func__);
- return false;
- }
-
- if (unlikely(NULL == pSkb))
+ if ( VOS_STATUS_SUCCESS !=
+ vos_pkt_get_os_packet(pPacket, (void**)&skb, VOS_FALSE ))
{
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
- "%s: NULL pointer", __func__);
+ "%s: OS PKT pointer is NULL", __func__);
return false;
}
- skb = (struct sk_buff *)pSkb;
-
- if (conversion)
- offset = VOS_ARP_SRC_IP_OFFSET + VOS_80211_8023_HEADER_OFFSET;
- else
- offset = VOS_ARP_SRC_IP_OFFSET;
-
if (pHddCtx->track_arp_ip ==
- (v_U32_t)(*(v_U32_t *)(skb->data + offset)))
+ (v_U32_t)(*(v_U32_t *)(skb->data + VOS_ARP_TARGET_IP_OFFSET)))
return true;
return false;
}
/**
- * vos_check_arp_rsp_src_ip() - check if the ARP is request and
- target IP is gateway
- * @pPacket: pointer to vos packet
- * @conversion: 802.3 to 802.11 frame conversion
- *
- * Return: true if the IP is of gateway or false otherwise
- */
-bool vos_check_arp_rsp_src_ip(void *pSkb, bool conversion)
-{
- v_CONTEXT_t pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
- struct sk_buff *skb;
- uint8_t offset;
-
- if(!pVosContext)
- {
- hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
- return false;
- }
-
- if (unlikely(NULL == pSkb))
- {
- VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
- "%s: NULL pointer", __func__);
- return false;
- }
-
- skb = (struct sk_buff *)pSkb;
-
- if (conversion)
- offset = VOS_PKT_ARP_OPCODE_OFFSET + VOS_80211_8023_HEADER_OFFSET;
- else
- offset = VOS_PKT_ARP_OPCODE_OFFSET;
-
- if (htons(VOS_PKT_ARPOP_REPLY) ==
- (uint16_t)(*(uint16_t *)(skb->data + offset)))
- {
- if (vos_check_arp_src_ip(skb, conversion))
- return true;
- }
-
- return false;
-}
-
-/**
* vos_update_arp_fw_tx_delivered() - update the ARP stats host to FW deliver
* count
*
@@ -3931,42 +3891,3 @@ void vos_update_arp_rx_drop_reorder(void)
pAdapter->hdd_stats.hddArpStats.rx_host_drop_reorder++;
}
-
-/**
- * vos_set_snoc_high_freq_voting() - enable/disable high freq voting
- * @enable: true if need to be enabled
- *
- * enable/disable high freq voting
- *
- * Return: Void
- */
-#ifdef HAVE_WCNSS_SNOC_HIGH_FREQ_VOTING
-void vos_set_snoc_high_freq_voting(bool enable)
-{
- VosContextType *vos_ctx = NULL;
-
- /* Get the Global VOSS Context */
- vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
-
- if (!vos_ctx) {
- VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- "%s: vos context is NULL", __func__);
- return;
- }
-
- spin_lock(&vos_ctx->freq_voting_lock);
- if (vos_ctx->snoc_high_freq_voting != enable)
- {
- vos_ctx->snoc_high_freq_voting = enable;
- spin_unlock(&vos_ctx->freq_voting_lock);
- wcnss_snoc_vote(enable);
- return;
- }
- spin_unlock(&vos_ctx->freq_voting_lock);
-}
-#else
-void vos_set_snoc_high_freq_voting(bool enable)
-{
- return;
-}
-#endif
diff --git a/drivers/staging/prima/CORE/VOSS/src/vos_diag.c b/drivers/staging/prima/CORE/VOSS/src/vos_diag.c
index 496ae473492..dbc2a5cae21 100644
--- a/drivers/staging/prima/CORE/VOSS/src/vos_diag.c
+++ b/drivers/staging/prima/CORE/VOSS/src/vos_diag.c
@@ -318,7 +318,7 @@ void vos_event_report_payload(v_U16_t event_Id, v_U16_t length, v_VOID_t *pPaylo
if( ptt_sock_send_msg_to_app(wmsg, 0,
ANI_NL_MSG_PUMAC, INVALID_PID, MSG_DONTWAIT) < 0) {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
("Ptt Socket error sending message to the app!!"));
vos_mem_free((v_VOID_t*)wmsg);
return;
diff --git a/drivers/staging/prima/CORE/VOSS/src/vos_sched.h b/drivers/staging/prima/CORE/VOSS/src/vos_sched.h
index 031809dac74..09b8038e1a9 100644
--- a/drivers/staging/prima/CORE/VOSS/src/vos_sched.h
+++ b/drivers/staging/prima/CORE/VOSS/src/vos_sched.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
diff --git a/drivers/staging/prima/CORE/WDA/inc/legacy/halMsgApi.h b/drivers/staging/prima/CORE/WDA/inc/legacy/halMsgApi.h
index 2711451ee74..83d0267f8df 100644
--- a/drivers/staging/prima/CORE/WDA/inc/legacy/halMsgApi.h
+++ b/drivers/staging/prima/CORE/WDA/inc/legacy/halMsgApi.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -73,6 +73,10 @@
//invalid channel id.
#define HAL_INVALID_CHANNEL_ID 0
+#ifdef SAP_AUTH_OFFLOAD
+#define MAX_CONNECT_REQ_LENGTH 512
+#endif
+
/* BSS index used when no BSS is associated with the station. For example,
* driver creates only one self station without valid BSS while scanning.
* Then this index is used to tell softmac that BSS is not valid.
@@ -288,6 +292,13 @@ typedef struct
tANI_U8 htLdpcCapable;
tANI_U8 vhtLdpcCapable;
+#ifdef SAP_AUTH_OFFLOAD
+ tANI_U8 dpuIndex;
+ tANI_U8 bcastDpuIndex;
+ tANI_U8 bcastMgmtDpuIdx;
+ tANI_U8 ucMgmtSig;
+#endif
+
} tAddStaParams, *tpAddStaParams;
@@ -1417,5 +1428,22 @@ typedef struct sNanRequest
tANI_U8 request_data[1];
} tNanRequest, *tpNanRequest;
+
+#ifdef SAP_AUTH_OFFLOAD
+struct sap_offload_add_sta_req
+{
+ tANI_U32 assoc_id;
+ tANI_U32 conn_req_len;
+ tANI_U8 conn_req[MAX_CONNECT_REQ_LENGTH];
+};
+struct sap_offload_del_sta_req
+{
+ tANI_U32 assoc_id;
+ tANI_U32 reason_code;
+ tANI_U32 flags;
+ tSirMacAddr sta_mac;
+};
+#endif /* SAP_AUTH_OFFLOAD */
+
#endif /* _HALMSGAPI_H_ */
diff --git a/drivers/staging/prima/CORE/WDA/inc/legacy/halTypes.h b/drivers/staging/prima/CORE/WDA/inc/legacy/halTypes.h
index 804925a4f93..67becef9bcf 100644
--- a/drivers/staging/prima/CORE/WDA/inc/legacy/halTypes.h
+++ b/drivers/staging/prima/CORE/WDA/inc/legacy/halTypes.h
@@ -219,6 +219,12 @@ typedef enum
#endif
//CMD not Queued in SME
eHAL_STATUS_CMD_NOT_QUEUED,
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ eHAL_STATUS_MBB_DEL_BSS_FAIL,
+ eHAL_STATUS_MBB_ADD_BSS_FAIL,
+#endif
+
// not a real status. Just a way to mark the maximum in the enum.
eHAL_STATUS_MAX
@@ -352,7 +358,7 @@ typedef enum
* supported by rome/prima hardware
*/
#define MIN_TX_PWR_CAP 8
-#define MAX_TX_PWR_CAP 30
+#define MAX_TX_PWR_CAP 22
/* Moving the miscellaneous defination required by UMAC are moved here from
* volansdefs.h */
diff --git a/drivers/staging/prima/CORE/WDA/inc/wlan_qct_wda.h b/drivers/staging/prima/CORE/WDA/inc/wlan_qct_wda.h
index fdc768d8ca4..997c80d5fcb 100644
--- a/drivers/staging/prima/CORE/WDA/inc/wlan_qct_wda.h
+++ b/drivers/staging/prima/CORE/WDA/inc/wlan_qct_wda.h
@@ -385,6 +385,8 @@ typedef eHalStatus (*pWDAAckFnTxComp)(tpAniSirGlobal, void *pData);
typedef void (*WDA_txFailIndCallback)(tANI_U8 *, tANI_U8);
#endif /* WLAN_FEATURE_RMC */
+typedef void (*WDA_suspend_req_callback)(tANI_U8 *, tANI_U8);
+
typedef struct
{
tANI_U16 ucValidStaIndex ;
@@ -525,10 +527,6 @@ typedef struct
uint8_t mgmt_pktfree_fail;
vos_lock_t mgmt_pkt_lock;
- /* debug connection status */
- bool tx_aggr;
- uint8_t sta_id;
- uint8_t tid;
} tWDA_CbContext ;
typedef struct
@@ -820,6 +818,11 @@ tBssSystemRole wdaGetGlobalSystemRole(tpAniSirGlobal pMac);
#ifdef WLAN_FEATURE_EXTSCAN
#define WDA_GET_EXTSCANFULLSCANRESIND(pRxMeta) (((WDI_DS_RxMetaInfoType*)(pRxMeta))->extscanBuffer)
#endif
+
+#ifdef SAP_AUTH_OFFLOAD
+#define WDA_GET_SAP_AUTHOFFLOADIND(pRxMeta) (((WDI_DS_RxMetaInfoType*)(pRxMeta))->indType)
+#endif
+
/* WDA_GET_RX_RSSI_DB ********************************************************/
// Volans RF
# define WDA_RSSI_OFFSET 100
@@ -1295,11 +1298,19 @@ tSirRetStatus uMacPostCtrlMsg(void* pSirGlobal, tSirMbMsg* pMb);
#define WDA_START_RSSI_MONITOR_REQ SIR_HAL_RSSI_MON_START_REQ
#define WDA_STOP_RSSI_MONITOR_REQ SIR_HAL_RSSI_MON_STOP_REQ
+#ifdef DHCP_SERVER_OFFLOAD
+#define WDA_SET_DHCP_SERVER_OFFLOAD_REQ SIR_HAL_SET_DHCP_SERVER_OFFLOAD_REQ
+#endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+#define WDA_SET_MDNS_OFFLOAD_CMD SIR_HAL_SET_MDNS_OFFLOAD
+#define WDA_SET_MDNS_FQDN_CMD SIR_HAL_SET_MDNS_FQDN
+#define WDA_SET_MDNS_RESPONSE_CMD SIR_HAL_SET_MDNS_RESPONSE
+#define WDA_GET_MDNS_STATUS_CMD SIR_HAL_GET_MDNS_STATUS
+#endif /* MDNS_OFFLOAD */
+
/* ARP Debug */
#define WDA_SET_ARP_STATS_REQ SIR_HAL_SET_ARP_STATS_REQ
#define WDA_GET_ARP_STATS_REQ SIR_HAL_GET_ARP_STATS_REQ
-#define WDA_TRIGGER_ADD_BA_REQ SIR_HAL_TRIGGER_ADD_BA_REQ
-#define WDA_GET_CON_STATUS SIR_HAL_GET_CON_STATUS
tSirRetStatus wdaPostCtrlMsg(tpAniSirGlobal pMac, tSirMsgQ *pMsg);
@@ -1362,6 +1373,21 @@ eHalStatus WDA_SetRegDomain(void * clientCtxt, v_REGDOMAIN_t regId,
#define WDA_PAUSE_TL_IND SIR_HAL_PAUSE_TL_IND
+#ifdef SAP_AUTH_OFFLOAD
+#define WDA_SAP_OFL_ADD_STA SIR_HAL_SAP_OFL_ADD_STA
+#define WDA_SAP_OFL_DEL_STA SIR_HAL_SAP_OFL_DEL_STA
+#define WDA_SET_SAP_AUTH_OFL SIR_HAL_SET_SAP_AUTH_OFL
+#endif /* SAP_AUTH_OFFLOAD */
+
+#ifdef WLAN_FEATURE_APFIND
+#define WDA_APFIND_SET_CMD SIR_HAL_APFIND_SET_CMD
+#define WDA_AP_FIND_IND SIR_HAL_AP_FIND_IND
+#endif /* WLAN_FEATURE_APFIND */
+
+#define WDA_CAP_TSF_REQ SIR_HAL_CAP_TSF_REQ
+#define WDA_GET_TSF_REQ SIR_HAL_GET_TSF_REQ
+
+
#define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40 // Bit 6 will be used to control BD rate for Management frames
#define halTxFrame(hHal, pFrmBuf, frmLen, frmType, txDir, tid, pCompFunc, pData, txFlag) \
@@ -2183,4 +2209,9 @@ void WDA_FWLoggingDXEdoneInd(v_U32_t logType);
void WDA_SetMgmtPktViaWQ5(v_BOOL_t sendMgmtPktViaWQ5);
+#define CAP_TSF_REQUEST 0
+#define GET_TSF_REQUEST 1
+
+VOS_STATUS WDA_ProcessCapTsfReq(tWDA_CbContext *pWDA, tSirCapTsfParams *params);
+VOS_STATUS WDA_ProcessGetTsfReq(tWDA_CbContext *pWDA, tSirCapTsfParams *params);
#endif
diff --git a/drivers/staging/prima/CORE/WDA/src/wlan_qct_wda.c b/drivers/staging/prima/CORE/WDA/src/wlan_qct_wda.c
index 83a5229007c..a26f81b875d 100644
--- a/drivers/staging/prima/CORE/WDA/src/wlan_qct_wda.c
+++ b/drivers/staging/prima/CORE/WDA/src/wlan_qct_wda.c
@@ -165,12 +165,7 @@ void WDA_lowLevelIndCallback(WDI_LowLevelIndType *wdiLowLevelInd,
static VOS_STATUS wdaCreateTimers(tWDA_CbContext *pWDA) ;
static VOS_STATUS wdaDestroyTimers(tWDA_CbContext *pWDA);
bool WDA_AllowAddBA(tpAniSirGlobal pMAc, tANI_U8 staId, tANI_U8 tid);
-void WDA_BaCheckActivity(tWDA_CbContext *pWDA, bool test_con);
-
-/* check connection status */
-void WDA_GetConnectionStatus(tWDA_CbContext *pWDA,
- getConStatusParams *conStatusParams);
-
+void WDA_BaCheckActivity(tWDA_CbContext *pWDA) ;
void WDA_TimerTrafficStatsInd(tWDA_CbContext *pWDA);
void WDA_HALDumpCmdCallback(WDI_HALDumpCmdRspParamsType *wdiRspParams, void* pUserData);
#ifdef WLAN_FEATURE_VOWIFI_11R
@@ -2399,6 +2394,37 @@ VOS_STATUS WDA_prepareConfigTLV(v_PVOID_t pVosContext,
}
tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct
+ sizeof(tHalCfg) + tlvStruct->length) ;
+ /* QWLAN_HAL_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL */
+ tlvStruct->type = QWLAN_HAL_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL ;
+ tlvStruct->length = sizeof(tANI_U32);
+ configDataValue = (tANI_U32 *)(tlvStruct + 1);
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL,
+ configDataValue ) != eSIR_SUCCESS)
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "Failed to get value for WNI_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL");
+ goto handle_failure;
+ }
+ tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct
+ + sizeof(tHalCfg) + tlvStruct->length) ;
+
+ wdiStartParams->usConfigBufferLen = (tANI_U8 *)tlvStruct - tlvStructStart ;
+
+ /* QWLAN_HAL_CFG_DISABLE_SCAN_DURING_SCO */
+ tlvStruct->type = QWLAN_HAL_CFG_DISABLE_SCAN_DURING_SCO ;
+ tlvStruct->length = sizeof(tANI_U32);
+ configDataValue = (tANI_U32 *)(tlvStruct + 1);
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_DISABLE_SCAN_DURING_SCO,
+ configDataValue ) != eSIR_SUCCESS)
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "Failed to get value for WNI_CFG_DISABLE_SCAN_DURING_SCO");
+ goto handle_failure;
+ }
+ tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct
+ + sizeof(tHalCfg) + tlvStruct->length) ;
/* QWLAN_HAL_CFG_CONS_BCNMISS_COUNT */
tlvStruct->type = QWLAN_HAL_CFG_CONS_BCNMISS_COUNT;
@@ -2430,22 +2456,20 @@ VOS_STATUS WDA_prepareConfigTLV(v_PVOID_t pVosContext,
tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct
+ sizeof(tHalCfg) + tlvStruct->length);
- wdiStartParams->usConfigBufferLen = (tANI_U8 *)tlvStruct - tlvStructStart ;
-
- /* QWLAN_HAL_CFG_DISABLE_SCAN_DURING_SCO */
- tlvStruct->type = QWLAN_HAL_CFG_DISABLE_SCAN_DURING_SCO ;
+ /* QWLAN_HAL_CFG_TRIGGER_NULLFRAME_BEFORE_HB */
+ tlvStruct->type = QWLAN_HAL_CFG_TRIGGER_NULLFRAME_BEFORE_HB;
tlvStruct->length = sizeof(tANI_U32);
configDataValue = (tANI_U32 *)(tlvStruct + 1);
-
- if (wlan_cfgGetInt(pMac, WNI_CFG_DISABLE_SCAN_DURING_SCO,
- configDataValue ) != eSIR_SUCCESS)
+ if(wlan_cfgGetInt(pMac, WNI_CFG_TRIGGER_NULLFRAME_BEFORE_HB,
+ configDataValue) != eSIR_SUCCESS)
{
VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
- "Failed to get value for WNI_CFG_DISABLE_SCAN_DURING_SCO");
+ "Failed to get WNI_CFG_TRIGGER_NULLFRAME_BEFORE_HB");
goto handle_failure;
}
+
tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct
- + sizeof(tHalCfg) + tlvStruct->length) ;
+ + sizeof(tHalCfg) + tlvStruct->length);
#ifdef WLAN_DEBUG
{
int i;
@@ -2479,10 +2503,339 @@ handle_failure:
vos_mem_free(configParam);
return VOS_STATUS_E_FAILURE;
}
+
+#ifdef DHCP_SERVER_OFFLOAD
+/**
+ * wda_dhcp_server_offload_rsp_callback() - response to the dhcp server offload
+ * @wdi_rsp: pointer to the dhcp server offload response
+ * @user_data: pointer to user data
+ *
+ * Return: None
+ */
+void wda_dhcp_server_offload_rsp_callback(wdi_dhcp_server_offload_rsp_param_t*
+ wdi_rsp,
+ void* user_data)
+{
+ tWDA_ReqParams *wda_params = (tWDA_ReqParams *)user_data;
+ sir_dhcp_srv_offload_info_t *dhcp_srv_offload_info;
+ VOS_STATUS status;
+
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "<------ %s " ,__func__);
+
+ if(NULL == wda_params)
+ {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: pWdaParams received NULL", __func__);
+ VOS_ASSERT(0);
+ return;
+ }
+
+ if(NULL == wda_params->wdaMsgParam)
+ {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: pWdaParams->wdaMsgParam is NULL", __func__);
+ VOS_ASSERT(0);
+ vos_mem_free(wda_params->wdaWdiApiMsgParam);
+ vos_mem_free(wda_params);
+ return;
+ }
+
+ dhcp_srv_offload_info = (sir_dhcp_srv_offload_info_t *)
+ wda_params->wdaMsgParam;
+
+ if(dhcp_srv_offload_info->dhcp_offload_callback)
+ {
+ dhcp_srv_offload_info->dhcp_offload_callback(
+ dhcp_srv_offload_info->dhcp_server_offload_cb_context,
+ CONVERT_WDI2VOS_STATUS(wdi_rsp->status));
+ }
+ else
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: pFWLoggingInitParams callback is NULL", __func__);
+ }
+
+ status = CONVERT_WDI2VOS_STATUS(wdi_rsp->status);
+ if (status)
+ {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: DHCP server offload failed with status=%d", __func__, status);
+ VOS_ASSERT(0);
+ }
+
+ vos_mem_free(wda_params->wdaWdiApiMsgParam);
+ vos_mem_free(wda_params->wdaMsgParam);
+ vos_mem_free(wda_params);
+ return;
+}
+#endif /* DHCP_SERVER_OFFLOAD */
+
+#ifdef MDNS_OFFLOAD
+/**
+ * wda_mdns_enable_rsp_callback() - response to the mdns enable server offload
+ * @wdi_rsp: pointer to the mdns enable offload response
+ * @user_data: pointer to user data
+ *
+ * Return: None
+ */
+void wda_mdns_enable_rsp_callback(wdi_mdns_enable_offload_rsp_param_t*
+ wdi_rsp,
+ void* user_data)
+{
+ tWDA_ReqParams *wda_params = (tWDA_ReqParams *)user_data;
+ sir_mdns_offload_info_t *mdns_offload_info;
+ VOS_STATUS status;
+
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "<------ %s " ,__func__);
+
+ if(NULL == wda_params)
+ {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: pWdaParams received NULL", __func__);
+ VOS_ASSERT(0);
+ return ;
+ }
+
+ if(NULL == wda_params->wdaMsgParam)
+ {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: pWdaParams->wdaMsgParam is NULL", __func__);
+ VOS_ASSERT(0);
+ vos_mem_free(wda_params->wdaWdiApiMsgParam);
+ vos_mem_free(wda_params);
+ return ;
+ }
+
+ mdns_offload_info = (sir_mdns_offload_info_t *)
+ wda_params->wdaMsgParam;
+
+ if(mdns_offload_info->mdns_enable_callback)
+ {
+ mdns_offload_info->mdns_enable_callback(mdns_offload_info->
+ mdns_enable_cb_context,
+ CONVERT_WDI2VOS_STATUS(wdi_rsp->
+ status));
+ }
+ else
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: mdns_enable callback is NULL", __func__);
+ }
+
+ status = CONVERT_WDI2VOS_STATUS(wdi_rsp->status);
+ if (status)
+ {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: MDNS offload failed with status=%d", __func__, status);
+ VOS_ASSERT(0);
+ }
+
+ vos_mem_free(wda_params->wdaWdiApiMsgParam);
+ vos_mem_free(wda_params->wdaMsgParam);
+ vos_mem_free(wda_params);
+
+ return;
+}
+
+/**
+ * wda_mdns_fqdn_rsp_callback() - response to the mdns fqdn offload
+ * @wdi_rsp: pointer to the mdns fqdn offload response
+ * @user_data: pointer to user data
+ *
+ * Return: None
+ */
+void wda_mdns_fqdn_rsp_callback(wdi_mdns_set_fqdn_rsp_param_t*
+ wdi_rsp,
+ void* user_data)
+{
+ tWDA_ReqParams *wda_params = (tWDA_ReqParams *)user_data;
+ sir_mdns_fqdn_info_t *mdns_fqdn_info;
+ VOS_STATUS status;
+
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "<------ %s " ,__func__);
+
+ if(NULL == wda_params)
+ {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: pWdaParams received NULL", __func__);
+ VOS_ASSERT(0);
+ return ;
+ }
+
+ if(NULL == wda_params->wdaMsgParam)
+ {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: pWdaParams->wdaMsgParam is NULL", __func__);
+ VOS_ASSERT(0);
+ vos_mem_free(wda_params->wdaWdiApiMsgParam);
+ vos_mem_free(wda_params);
+ return ;
+ }
+
+ mdns_fqdn_info = (sir_mdns_fqdn_info_t *)
+ wda_params->wdaMsgParam;
+
+ if(mdns_fqdn_info->mdns_fqdn_callback)
+ {
+ mdns_fqdn_info->mdns_fqdn_callback(mdns_fqdn_info->
+ mdns_fqdn_cb_context,
+ CONVERT_WDI2VOS_STATUS(wdi_rsp->
+ status));
+ }
+ else
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: mdns_fqdn callback is NULL", __func__);
+ }
+
+ status = CONVERT_WDI2VOS_STATUS(wdi_rsp->status);
+ if (status)
+ {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: MDNS FQDN offload failed with status=%d", __func__, status);
+ VOS_ASSERT(0);
+ }
+
+ vos_mem_free(wda_params->wdaWdiApiMsgParam);
+ vos_mem_free(wda_params->wdaMsgParam);
+ vos_mem_free(wda_params);
+
+ return;
+}
+
+/**
+ * wda_mdns_resp_rsp_callback() - response to the mdns resp offload
+ * @wdi_rsp: pointer to the mdns fqdn offload response
+ * @user_data: pointer to user data
+ *
+ * Return: None
+ */
+void wda_mdns_resp_rsp_callback
+(
+ wdi_mdns_set_rsp_param_t*
+ wdi_rsp,
+ void* user_data)
+{
+ tWDA_ReqParams *wda_params = (tWDA_ReqParams *)user_data;
+ sir_mdns_resp_info_t *mdns_resp_info;
+ VOS_STATUS status;
+
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "<------ %s " ,__func__);
+
+ if(NULL == wda_params)
+ {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: pWdaParams received NULL", __func__);
+ VOS_ASSERT(0);
+ return ;
+ }
+
+ if(NULL == wda_params->wdaMsgParam)
+ {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: pWdaParams->wdaMsgParam is NULL", __func__);
+ VOS_ASSERT(0);
+ vos_mem_free(wda_params->wdaWdiApiMsgParam);
+ vos_mem_free(wda_params);
+ return ;
+ }
+
+ mdns_resp_info = (sir_mdns_resp_info_t *)
+ wda_params->wdaMsgParam;
+
+ if(mdns_resp_info->mdns_resp_callback)
+ {
+ mdns_resp_info->mdns_resp_callback(mdns_resp_info->
+ mdns_resp_cb_context,
+ CONVERT_WDI2VOS_STATUS(wdi_rsp->
+ status));
+ }
+ else
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: mdns_fqdn callback is NULL", __func__);
+ }
+
+ status = CONVERT_WDI2VOS_STATUS(wdi_rsp->status);
+ if (status)
+ {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: MDNS FQDN offload failed with status=%d", __func__, status);
+ VOS_ASSERT(0);
+ }
+
+ vos_mem_free(wda_params->wdaWdiApiMsgParam);
+ vos_mem_free(wda_params->wdaMsgParam);
+ vos_mem_free(wda_params);
+
+ return;
+}
+
+/**
+ * wda_get_stats_rsp_callback() - response to the mdns stats offload
+ * @wdi_rsp: pointer to the mdns fqdn offload response
+ * @user_data: pointer to user data
+ *
+ * Return: None
+ */
+void wda_get_stats_rsp_callback
+(
+ wdi_mdns_stats_rsp_param_t*
+ wdi_rsp,
+ void* user_data)
+{
+ tWDA_ReqParams *wda_params = (tWDA_ReqParams *)user_data;
+ sir_get_mdns_stats_info_t *mdns_stats_info;
+ VOS_STATUS status;
+
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "<------ %s " ,__func__);
+
+ if(NULL == wda_params)
+ {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: pWdaParams received NULL", __func__);
+ VOS_ASSERT(0);
+ return ;
+ }
+
+ if(NULL == wda_params->wdaMsgParam)
+ {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: pWdaParams->wdaMsgParam is NULL", __func__);
+ VOS_ASSERT(0);
+ vos_mem_free(wda_params->wdaWdiApiMsgParam);
+ vos_mem_free(wda_params);
+ return ;
+ }
+
+ mdns_stats_info = (sir_get_mdns_stats_info_t *)
+ wda_params->wdaMsgParam;
+
+ status = CONVERT_WDI2VOS_STATUS(wdi_rsp->status);
+ if (status)
+ {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: MDNS FQDN offload failed with status=%d", __func__, status);
+ VOS_ASSERT(0);
+ }
+
+ vos_mem_free(wda_params->wdaWdiApiMsgParam);
+ vos_mem_free(wda_params->wdaMsgParam);
+ vos_mem_free(wda_params);
+
+ return;
+}
+#endif /* MDNS_OFFLOAD */
+
/*
* FUNCTION: WDA_wdiCompleteCB
* call the voss call back function
- */
+ */
void WDA_stopCallback(WDI_Status status, void* pUserData)
{
tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData;
@@ -4370,7 +4723,95 @@ VOS_STATUS WDA_ProcessAddStaReq(tWDA_CbContext *pWDA,
}
return CONVERT_WDI2VOS_STATUS(status) ;
}
+#ifdef SAP_AUTH_OFFLOAD
+
+/**
+ * WDA_ProcessSapAuthOffloadAddStaReq(): process add sta command.
+ *
+ * @pWDA: WDA Call back context
+ * @addStaReqParam: Add sta request params
+ *
+ * This function process sta params and store them to WDA layer.
+ * It will register station entry to mempool as well.
+ * As station is already in associated state in firmware this
+ * function doesnt send any request to firmware and wait for response,
+ * instead of that this function will send response from here.
+ *
+ * Return: Return VOS_STATUS
+ */
+VOS_STATUS WDA_ProcessSapAuthOffloadAddStaReq(tWDA_CbContext *pWDA,
+ tAddStaParams *addStaReqParam)
+{
+ WDI_Status status = WDI_STATUS_SUCCESS ;
+ WDI_AddStaParams wdiAddSTAParam = {0};
+ WDI_ConfigSTAReqParamsType *wdiConfigStaReqParam =
+ (WDI_ConfigSTAReqParamsType *)vos_mem_malloc(
+ sizeof(WDI_ConfigSTAReqParamsType)) ;
+
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "------> %s " ,__func__);
+ if (NULL == wdiConfigStaReqParam)
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: VOS MEM Alloc Failure", __func__);
+ VOS_ASSERT(0);
+ return VOS_STATUS_E_NOMEM;
+ }
+
+ vos_mem_set(wdiConfigStaReqParam, sizeof(WDI_ConfigSTAReqParamsType), 0);
+ /* update STA params into WDI structure */
+ WDA_UpdateSTAParams(pWDA, &wdiConfigStaReqParam->wdiReqInfo,
+ addStaReqParam);
+ wdiAddSTAParam.ucSTAIdx = wdiConfigStaReqParam->wdiReqInfo.staIdx;
+ wdiAddSTAParam.ucStaType = WDI_STA_ENTRY_PEER;
+ /* MAC Address of STA */
+ wpalMemoryCopy(wdiAddSTAParam.staMacAddr,
+ wdiConfigStaReqParam->wdiReqInfo.macSTA,
+ WDI_MAC_ADDR_LEN);
+
+ wpalMemoryCopy(wdiAddSTAParam.macBSSID,
+ wdiConfigStaReqParam->wdiReqInfo.macBSSID,
+ WDI_MAC_ADDR_LEN);
+
+ wdiAddSTAParam.dpuIndex = addStaReqParam->dpuIndex;
+ wdiAddSTAParam.dpuSig = addStaReqParam->ucUcastSig;
+ wdiAddSTAParam.bcastDpuIndex = addStaReqParam->bcastDpuIndex;
+ wdiAddSTAParam.bcastDpuSignature = addStaReqParam->ucBcastSig;
+ wdiAddSTAParam.bcastMgmtDpuIndex = addStaReqParam->bcastMgmtDpuIdx;
+ wdiAddSTAParam.bcastMgmtDpuSignature = addStaReqParam->ucMgmtSig;
+ wdiAddSTAParam.ucWmmEnabled = addStaReqParam->wmmEnabled;
+ wdiAddSTAParam.ucRmfEnabled = addStaReqParam->rmfEnabled;
+ wdiAddSTAParam.ucBSSIdx = addStaReqParam->bssIdx;
+ wdiAddSTAParam.ucHTCapable = addStaReqParam->htCapable;
+
+
+ WDI_STATableAddSta(pWDA->pWdiContext, &wdiAddSTAParam);
+ pWDA->wdaStaInfo[wdiConfigStaReqParam->wdiReqInfo.staIdx].ucValidStaIndex =
+ WDA_VALID_STA_INDEX;
+ pWDA->wdaStaInfo[wdiConfigStaReqParam->wdiReqInfo.staIdx].currentOperChan =
+ addStaReqParam->currentOperChan;
+
+ if (WDI_STATUS_SUCCESS !=
+ WDI_STATableFindStaidByAddr(pWDA->pWdiContext,
+ wdiConfigStaReqParam->wdiReqInfo.macSTA,
+ (wpt_uint8 *)&wdiConfigStaReqParam->wdiReqInfo.staIdx))
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: Failed to get selfStaIdx!", __func__);
+ }
+ if (WDI_DS_AddSTAMemPool(pWDA->pWdiContext,
+ wdiConfigStaReqParam->wdiReqInfo.staIdx))
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: add STA into mempool fail", __func__);
+ VOS_ASSERT(0) ;
+ }
+ vos_mem_free(wdiConfigStaReqParam);
+ WDA_SendMsg(pWDA, WDA_ADD_STA_RSP, (void *)addStaReqParam, 0) ;
+ return status;
+}
+#endif
/*
* FUNCTION: WDA_DelBSSRspCallback
* Dens DEL BSS RSP back to PE
@@ -4636,6 +5077,45 @@ void WDA_DelSTAReqCallback(WDI_Status wdiStatus,
return ;
}
+#ifdef SAP_AUTH_OFFLOAD
+/**
+ * WDA_ProcessSapAuthOffloadDelStaReq(): process del sta command.
+ *
+ * @pWDA: WDA Call back context
+ * @delStaParam: Del sta request params
+ *
+ * This function process sta params and remove entry from WDA layer.
+ * It will unregister station entry from mempool as well.
+ * As station is already in disassociated state in firmware this
+ * function doesn't send any request to firmware and wait for response,
+ * instead of that this function will send response from here.
+ *
+ * Return: Return VOS_STATUS
+ */
+void WDA_ProcessSapAuthOffloadDelStaReq(tWDA_CbContext *pWDA,
+ tDeleteStaParams *delStaParam)
+
+{
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "------> %s " ,__func__);
+
+ if (WDI_DS_DelSTAMemPool(pWDA->pWdiContext, delStaParam->staIdx))
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: DEL STA from MemPool Fail", __func__);
+ // VOS_ASSERT(0) ;
+ }
+ WLANTL_StartForwarding(delStaParam->staIdx, 0, 0);
+ WDI_STATableDelSta(pWDA->pWdiContext, delStaParam->staIdx);
+ pWDA->wdaStaInfo[delStaParam->staIdx].ucValidStaIndex =
+ WDA_INVALID_STA_INDEX;
+ pWDA->wdaStaInfo[delStaParam->staIdx].currentOperChan = 0;
+ pWDA->wdaStaInfo[delStaParam->staIdx].ucUseBaBitmap = 0;
+ WDA_SendMsg(pWDA, WDA_DELETE_STA_RSP, (void *)delStaParam, 0);
+ return ;
+}
+#endif
+
/*
* FUNCTION: WDA_ProcessDelStaReq
* Init DEL STA req with WDI
@@ -5362,6 +5842,9 @@ static inline tANI_U16 WDA_ConvertWniCfgIdToHALCfgId(v_U32_t wniCfgId)
return QWLAN_HAL_CFG_ENABLE_RTSCTS_HTVHT;
case WNI_CFG_ENABLE_MC_ADDR_LIST:
return QWLAN_HAL_CFG_ENABLE_MC_ADDR_LIST;
+ case WNI_CFG_HEART_BEAT_THRESHOLD:
+ return QWLAN_HAL_CFG_PS_HEART_BEAT_THRESHOLD;
+
default:
{
VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
@@ -11060,6 +11543,55 @@ void WDA_WdiIndicationCallback( WDI_Status wdiStatus,
VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
"<------ %s " ,__func__);
}
+
+/**
+ * WDA_ProcessWlanSuspendIndCallback: callback API for WDA_ProcessWlanSuspendInd
+ * @wdiStatus: wdi status
+ * @pUserData: suspend params
+ *
+ * Return: None
+ */
+void WDA_ProcessWlanSuspendIndCallback(WDI_Status wdiStatus, void* pUserData)
+{
+ tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData;
+ tSirWlanSuspendParam *pWlanSuspendParam;
+
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "<------ %s, wdiStatus: %d", __func__, wdiStatus);
+
+ if(NULL == pWdaParams)
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: pWdaParams received NULL", __func__);
+ return;
+ }
+
+ pWlanSuspendParam = (tSirWlanSuspendParam *)pWdaParams->wdaMsgParam;
+ if (pWlanSuspendParam == NULL)
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: suspend params NULL", __func__);
+ vos_mem_free(pWdaParams);
+ return;
+ }
+ if (pWlanSuspendParam->wlan_sus_callback)
+ {
+ pWlanSuspendParam->wlan_sus_callback(pWlanSuspendParam->context,
+ CONVERT_WDI2VOS_STATUS(wdiStatus));
+ }
+ else
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: wlan suspend callback is NULL", __func__);
+ }
+ if (pWdaParams->wdaMsgParam) {
+ vos_mem_free(pWdaParams->wdaMsgParam);
+ pWdaParams->wdaMsgParam = NULL;
+ }
+ vos_mem_free(pWdaParams);
+ return;
+}
+
/*
* FUNCTION: WDA_ProcessWlanSuspendInd
*
@@ -11069,12 +11601,22 @@ VOS_STATUS WDA_ProcessWlanSuspendInd(tWDA_CbContext *pWDA,
{
WDI_Status wdiStatus;
WDI_SuspendParamsType wdiSuspendParams;
+ tWDA_ReqParams *pWdaParams;
+
VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
"------> %s " ,__func__);
wdiSuspendParams.wdiSuspendParams.ucConfiguredMcstBcstFilterSetting =
pWlanSuspendParam->configuredMcstBcstFilterSetting;
- wdiSuspendParams.wdiReqStatusCB = WDA_WdiIndicationCallback;
- wdiSuspendParams.pUserData = pWDA;
+ wdiSuspendParams.wdiReqStatusCB = WDA_ProcessWlanSuspendIndCallback;
+
+ pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams));
+ if (!pWdaParams)
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s memory allocation failed" ,__func__);
+ pWdaParams->pWdaContext = pWDA;
+ pWdaParams->wdaMsgParam = pWlanSuspendParam;
+ wdiSuspendParams.pUserData = pWdaParams;
+
VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, "%s: %d" ,__func__, pWlanSuspendParam->configuredMcstBcstFilterSetting);
wdiStatus = WDI_HostSuspendInd(&wdiSuspendParams);
if(WDI_STATUS_PENDING == wdiStatus)
@@ -11087,7 +11629,6 @@ VOS_STATUS WDA_ProcessWlanSuspendInd(tWDA_CbContext *pWDA,
VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
"Failure in %s:%d ",__func__,__LINE__ );
}
- vos_mem_free(pWlanSuspendParam);
return CONVERT_WDI2VOS_STATUS(wdiStatus) ;
}
@@ -11764,7 +12305,7 @@ VOS_STATUS WDA_ProcessHostOffloadReq(tWDA_CbContext *pWDA,
if(IS_WDI_STATUS_FAILURE(wstatus))
{
- VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_WARN,
"Failure in host offload REQ WDI API, free all the memory %d",
wstatus);
status = CONVERT_WDI2VOS_STATUS(wstatus);
@@ -14951,6 +15492,50 @@ WDA_ProcessIbssPeerInfoReq(tWDA_CbContext *pWDA,
}
+#ifdef WLAN_FEATURE_APFIND
+/*
+ * FUNCTION: WDA_Process_apfind_set_cmd
+ * Forward AP find config request to WDI
+ */
+VOS_STATUS WDA_Process_apfind_set_cmd(tWDA_CbContext *pWDA,
+ struct hal_apfind_request *ap_find_req)
+{
+ WDI_Status status;
+ struct WDI_APFind_cmd *wdi_ap_find_cmd;
+
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "------> %s " ,__func__);
+ if (NULL == ap_find_req)
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: apfind_req info received NULL", __func__);
+ VOS_ASSERT(0) ;
+ return VOS_STATUS_E_FAULT;
+ }
+
+ wdi_ap_find_cmd = (struct WDI_APFind_cmd *)vos_mem_malloc(
+ sizeof(struct hal_apfind_request) + ap_find_req->request_data_len);
+
+ wdi_ap_find_cmd->data_len = ap_find_req->request_data_len;
+ vos_mem_copy(wdi_ap_find_cmd->data, ap_find_req->request_data,
+ ap_find_req->request_data_len);
+
+ status = WDI_process_ap_find_cmd(wdi_ap_find_cmd);
+ if (WDI_STATUS_PENDING == status) {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ FL("pending status received"));
+ } else if (WDI_STATUS_SUCCESS_SYNC != status &&
+ (WDI_STATUS_SUCCESS != status)) {
+
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ FL("Failure in process_sap_auth_offload API %d"), status);
+
+ }
+ vos_mem_free(wdi_ap_find_cmd);
+ return CONVERT_WDI2VOS_STATUS(status) ;
+}
+#endif
+
/*
* FUNCTION: WDA_ProcessTXFailMonitorInd
* Forward TX Fail Monitor to WDI
@@ -15303,6 +15888,74 @@ VOS_STATUS wda_process_set_allowed_action_frames_ind(tWDA_CbContext *pWDA,
return CONVERT_WDI2VOS_STATUS(status) ;
}
+#ifdef SAP_AUTH_OFFLOAD
+VOS_STATUS wda_process_sap_auth_offload(tWDA_CbContext *pWDA,
+ struct tSirSapOffloadInfo *sap_auth_offload_info)
+{
+ WDI_Status status = WDI_STATUS_SUCCESS;
+ struct WDI_sap_ofl_enable_params *sap_ofl_enable_cmd;
+ v_U16_t psk_len, psk_len_padded;
+
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "------> %s " ,__func__);
+
+ if(NULL == sap_auth_offload_info)
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: sap_auth_offload_info received NULL", __func__);
+ VOS_ASSERT(0) ;
+ return VOS_STATUS_E_FAULT;
+ }
+ psk_len = sap_auth_offload_info->key_len;
+ psk_len_padded = roundup(psk_len, sizeof(v_U32_t));
+
+ sap_ofl_enable_cmd = (struct WDI_sap_ofl_enable_params*)
+ vos_mem_malloc(sizeof
+ (*sap_ofl_enable_cmd));
+ if (!sap_ofl_enable_cmd) {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: VOS MEM Alloc Failure", __func__);
+ vos_mem_free(sap_auth_offload_info);
+ return VOS_STATUS_E_NOMEM;
+ }
+ vos_mem_zero(sap_ofl_enable_cmd, sizeof(*sap_ofl_enable_cmd));
+ vos_mem_copy(sap_ofl_enable_cmd->macAddr,
+ sap_auth_offload_info->macAddr, VOS_MAC_ADDRESS_LEN);
+
+ sap_ofl_enable_cmd->enable = sap_auth_offload_info->sap_auth_offload_enable;
+ sap_ofl_enable_cmd->psk_len = psk_len;
+ switch (sap_auth_offload_info->sap_auth_offload_sec_type) {
+ case eSIR_OFFLOAD_WPA2PSK_CCMP:
+ sap_ofl_enable_cmd->rsn_authmode = WDI_AUTH_TYPE_RSN_PSK;
+ sap_ofl_enable_cmd->rsn_mcastcipherset = WDI_ED_CCMP;
+ sap_ofl_enable_cmd->rsn_ucastcipherset = WDI_ED_CCMP;
+ break;
+ case eSIR_OFFLOAD_NONE:
+ default:
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "Set SAP AP Auth offload with none support security type\n");
+ break;
+ }
+ vos_mem_copy(sap_ofl_enable_cmd->key, sap_auth_offload_info->key, psk_len);
+
+ status = WDI_process_sap_auth_offload(sap_ofl_enable_cmd);
+
+ if (WDI_STATUS_PENDING == status) {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ FL("pending status received"));
+ } else if (WDI_STATUS_SUCCESS_SYNC != status &&
+ (WDI_STATUS_SUCCESS != status)) {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ FL("Failure in process_sap_auth_offload API %d"), status);
+ }
+
+ vos_mem_free(sap_ofl_enable_cmd);
+ vos_mem_free(sap_auth_offload_info);
+ return CONVERT_WDI2VOS_STATUS(status) ;
+
+}
+#endif
+
/*
* FUNCTION: WDA_ProcessBcnMissPenaltyCount
* Request to WDI.
@@ -15590,6 +16243,409 @@ VOS_STATUS WDA_ProcessGetARPStatsReq(tWDA_CbContext *pWDA,
return wdi_status;
}
+
+#ifdef DHCP_SERVER_OFFLOAD
+/**
+ * wda_process_dhcpserver_offload_req() - wda api to set dhcp server offload
+ * @wda_handle: pointer to wda handle
+ * @dhcp_server_offload_info: dhcp server offload info
+ *
+ * Return: status
+ * 0 - success or else failure
+ */
+static int wda_process_dhcpserver_offload_req(tWDA_CbContext *wda_handle,
+ sir_dhcp_srv_offload_info_t
+ *dhcp_server_offload_info)
+{
+ wdi_set_dhcp_server_offload_t *dhcp_info;
+ tWDA_ReqParams *wda_params;
+ WDI_Status wstatus;
+ VOS_STATUS status = VOS_STATUS_SUCCESS;
+
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ FL("---> %s"), __func__);
+
+ if(NULL == dhcp_server_offload_info)
+ {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: dhcp_server_offload_info received NULL",
+ __func__);
+ VOS_ASSERT(0) ;
+ return VOS_STATUS_E_FAULT;
+ }
+
+ dhcp_info = (wdi_set_dhcp_server_offload_t *)
+ vos_mem_malloc(sizeof(*dhcp_info));
+ if (!dhcp_info) {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "Failed to allocate buffer to send "
+ "set_dhcp_server_offload cmd");
+ vos_mem_free(dhcp_server_offload_info);
+ return VOS_STATUS_E_NOMEM;
+ }
+
+ vos_mem_zero(dhcp_info, sizeof(*dhcp_info));
+
+ wda_params = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ;
+ if(NULL == wda_params)
+ {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: VOS MEM Alloc Failure", __func__);
+ VOS_ASSERT(0);
+ vos_mem_free(dhcp_info);
+ vos_mem_free(dhcp_server_offload_info);
+ return VOS_STATUS_E_NOMEM;
+ }
+
+ dhcp_info->bssidx = dhcp_server_offload_info->bssidx;
+ dhcp_info->enable = dhcp_server_offload_info->dhcp_srv_offload_enabled;
+ dhcp_info->num_client = dhcp_server_offload_info->dhcp_client_num;
+ dhcp_info->srv_ipv4 = dhcp_server_offload_info->dhcp_srv_ip;
+ dhcp_info->start_lsb = dhcp_server_offload_info->start_lsb;
+
+ wda_params->pWdaContext = wda_handle;
+ wda_params->wdaMsgParam = dhcp_server_offload_info;
+ wda_params->wdaWdiApiMsgParam = (void *)dhcp_info;
+
+ wstatus = wdi_process_dhcpserver_offload_req(dhcp_info,
+ (wdi_dhcp_srv_offload_rsp_cb)
+ wda_dhcp_server_offload_rsp_callback,
+ wda_params);
+ if(IS_WDI_STATUS_FAILURE(wstatus))
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "Failed to send set_dhcp_server_offload cmd" );
+ status = CONVERT_WDI2VOS_STATUS(wstatus);
+ vos_mem_free(wda_params->wdaWdiApiMsgParam) ;
+ vos_mem_free(wda_params->wdaMsgParam);
+ vos_mem_free(wda_params);
+ }
+
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "Set dhcp server offload");
+ return status;
+}
+#endif /* DHCP_SERVER_OFFLOAD */
+
+#ifdef MDNS_OFFLOAD
+/**
+ * wda_set_mdns_offload_req() - wda api to set mdns offload
+ * @wda_handle: wda handle
+ * @mdns_offload_info: mdns offload info
+ *
+ * Return - 0 for success or else failure
+ */
+static int
+wda_set_mdns_offload_req(tWDA_CbContext *wda_handle,
+ sir_mdns_offload_info_t *mdns_offload_info)
+{
+ wdi_mdns_enable_offload_cmd_req *mdns_info;
+ tWDA_ReqParams *wda_params;
+ WDI_Status wstatus;
+ VOS_STATUS status = VOS_STATUS_SUCCESS;
+
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ FL("---> %s"), __func__);
+
+ if(NULL == mdns_offload_info)
+ {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: set_mdns_offload received NULL",
+ __func__);
+ VOS_ASSERT(0) ;
+ return VOS_STATUS_E_FAULT;
+ }
+
+ mdns_info = (wdi_mdns_enable_offload_cmd_req *)
+ vos_mem_malloc(sizeof(*mdns_info));
+ if (!mdns_info) {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "Failed to allocate buffer to send "
+ "set_mdns_offload cmd");
+ vos_mem_free(mdns_offload_info);
+ return VOS_STATUS_E_NOMEM;
+ }
+
+ vos_mem_zero(mdns_info, sizeof(*mdns_info));
+
+ wda_params = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ;
+ if(NULL == wda_params)
+ {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: VOS MEM Alloc Failure", __func__);
+ VOS_ASSERT(0);
+ vos_mem_free(mdns_info);
+ vos_mem_free(mdns_offload_info);
+ return VOS_STATUS_E_NOMEM;
+ }
+
+ mdns_info->bss_idx = mdns_offload_info->bss_idx;
+ mdns_info->enable = mdns_offload_info->enable;
+
+ wda_params->pWdaContext = wda_handle;
+ wda_params->wdaMsgParam = mdns_offload_info;
+ wda_params->wdaWdiApiMsgParam = (void *)mdns_info;
+
+ wstatus = wdi_set_mdns_offload_req(mdns_info,
+ (wdi_mdns_enable_rsp_cb)
+ wda_mdns_enable_rsp_callback,
+ wda_params);
+ if(IS_WDI_STATUS_FAILURE(wstatus))
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "Failed to send wdi_set_mdns_offload_req cmd" );
+ status = CONVERT_WDI2VOS_STATUS(wstatus);
+ vos_mem_free(wda_params->wdaWdiApiMsgParam) ;
+ vos_mem_free(wda_params->wdaMsgParam);
+ vos_mem_free(wda_params);
+ }
+
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "mdns enabled!");
+ return status;
+
+}
+
+/**
+ * wda_set_mdns_fqdn_req() - wda api to set mdns fqdn offload
+ * @wda_handle: wda handle
+ * @mdns_fqdn_info: mdns fqdn offload info
+ *
+ * Return - 0 for success or else failure
+ */
+static int
+wda_set_mdns_fqdn_req(tWDA_CbContext *wda_handle,
+ sir_mdns_fqdn_info_t *mdns_fqdn_info)
+{
+ wdi_mdns_set_fqdn_cmd_req *fqdn_info;
+ tWDA_ReqParams *wda_params;
+ WDI_Status wstatus;
+ VOS_STATUS status = VOS_STATUS_SUCCESS;
+
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ FL("---> %s"), __func__);
+
+ if(NULL == mdns_fqdn_info)
+ {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: set_mdns_fqdn received NULL",
+ __func__);
+ VOS_ASSERT(0) ;
+ return VOS_STATUS_E_FAULT;
+ }
+
+ fqdn_info = (wdi_mdns_set_fqdn_cmd_req *)
+ vos_mem_malloc(sizeof(*fqdn_info));
+ if (!fqdn_info) {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "Failed to allocate buffer to send "
+ "set_mdns_fqdn cmd");
+ vos_mem_free(mdns_fqdn_info);
+ return VOS_STATUS_E_NOMEM;
+ }
+
+ vos_mem_zero(fqdn_info, sizeof(*fqdn_info));
+
+ wda_params = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams));
+ if(NULL == wda_params)
+ {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: VOS MEM Alloc Failure", __func__);
+ VOS_ASSERT(0);
+ vos_mem_free(fqdn_info);
+ vos_mem_free(mdns_fqdn_info);
+ return VOS_STATUS_E_NOMEM;
+ }
+
+ fqdn_info->bss_idx = mdns_fqdn_info->bss_idx;
+ fqdn_info->type = mdns_fqdn_info->fqdn_type;
+ fqdn_info->fqdn_len = mdns_fqdn_info->fqdn_len;
+ vos_mem_copy(fqdn_info->fqdn_data, mdns_fqdn_info->fqdn_data,
+ mdns_fqdn_info->fqdn_len);
+ fqdn_info->fqdn_data[mdns_fqdn_info->fqdn_len] = '\0';
+
+ wda_params->pWdaContext = wda_handle;
+ wda_params->wdaMsgParam = mdns_fqdn_info;
+ wda_params->wdaWdiApiMsgParam = (void *)fqdn_info;
+
+ wstatus = wdi_set_mdns_fqdn_req(fqdn_info,
+ (wdi_mdns_fqdn_rsp_cb)
+ wda_mdns_fqdn_rsp_callback,
+ wda_params);
+ if(IS_WDI_STATUS_FAILURE(wstatus))
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "Failed to send wdi_set_mdns_fqdn_req cmd" );
+ status = CONVERT_WDI2VOS_STATUS(wstatus);
+ vos_mem_free(wda_params->wdaWdiApiMsgParam) ;
+ vos_mem_free(wda_params->wdaMsgParam);
+ vos_mem_free(wda_params);
+ }
+
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "mDNS FQDN set");
+ return status;
+}
+
+/**
+ * wda_set_mdns_response_req() - wda api to set mdns resp offload
+ * @wda_handle: wda handle
+ * @mdns_rsp_info: mdns resp offload info
+ *
+ * Return - 0 for success or else failure
+ */
+static int
+wda_set_mdns_response_req(tWDA_CbContext *wda_handle,
+ sir_mdns_resp_info_t *mdns_rsp_info)
+{
+ wdi_mdns_set_resp_req *rsp_info;
+ tWDA_ReqParams *wda_params;
+ WDI_Status wstatus;
+ VOS_STATUS status = VOS_STATUS_SUCCESS;
+
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ FL("---> %s"), __func__);
+
+ if(NULL == mdns_rsp_info)
+ {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: dhcp_server_offload_info received NULL",
+ __func__);
+ VOS_ASSERT(0) ;
+ return VOS_STATUS_E_FAULT;
+ }
+
+ rsp_info = (wdi_mdns_set_resp_req *)
+ vos_mem_malloc(sizeof(*rsp_info));
+ if (!rsp_info) {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "Failed to allocate buffer to send "
+ "wdi_set_mdns_response_req cmd");
+ vos_mem_free(mdns_rsp_info);
+ return VOS_STATUS_E_NOMEM;
+ }
+
+ vos_mem_zero(rsp_info, sizeof(*rsp_info));
+
+ wda_params = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ;
+ if(NULL == wda_params)
+ {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: VOS MEM Alloc Failure", __func__);
+ VOS_ASSERT(0);
+ vos_mem_free(rsp_info);
+ vos_mem_free(mdns_rsp_info);
+ return VOS_STATUS_E_NOMEM;
+ }
+
+ rsp_info->bss_idx = mdns_rsp_info->bss_idx;
+ rsp_info->ar_count = mdns_rsp_info->resourceRecord_count;
+ rsp_info->resp_len = mdns_rsp_info->resp_len;
+ vos_mem_copy(rsp_info->resp_data, mdns_rsp_info->resp_data,
+ mdns_rsp_info->resp_len);
+ rsp_info->resp_data[mdns_rsp_info->resp_len] = '\0';
+
+ wda_params->pWdaContext = wda_handle;
+ wda_params->wdaMsgParam = mdns_rsp_info;
+ wda_params->wdaWdiApiMsgParam = (void *)rsp_info;
+
+ wstatus = wdi_set_mdns_response_req(rsp_info,
+ (wdi_mdns_resp_rsp_cb)
+ wda_mdns_resp_rsp_callback,
+ wda_params);
+ if(IS_WDI_STATUS_FAILURE(wstatus))
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "Failed to send wdi_set_mdns_response_req cmd" );
+ status = CONVERT_WDI2VOS_STATUS(wstatus);
+ vos_mem_free(wda_params->wdaWdiApiMsgParam) ;
+ vos_mem_free(wda_params->wdaMsgParam);
+ vos_mem_free(wda_params);
+ }
+
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "mDNS Response set!");
+ return status;
+}
+
+/**
+ * wda_get_mdns_stats_req() - wda api to get mdns stats
+ * @wda_handle: wda handle
+ * @mdns_info: mdns info
+ *
+ * Return - 0 for success or else failure
+ */
+static int
+wda_get_mdns_stats_req(tWDA_CbContext *wda_handle,
+ sir_get_mdns_stats_info_t *mdns_info)
+{
+ wdi_mdns_get_stats_req *status_info;
+ tWDA_ReqParams *wda_params;
+ WDI_Status wstatus;
+
+ VOS_STATUS status = VOS_STATUS_SUCCESS;
+
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ FL("---> %s"), __func__);
+
+ if(NULL == mdns_info)
+ {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: dhcp_server_offload_info received NULL",
+ __func__);
+ VOS_ASSERT(0) ;
+ return VOS_STATUS_E_FAULT;
+ }
+
+ status_info = (wdi_mdns_get_stats_req *)
+ vos_mem_malloc(sizeof(*status_info));
+ if (!status_info) {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "Failed to allocate buffer to send "
+ "wdi_set_mdns_response_req cmd");
+ vos_mem_free(mdns_info);
+ return VOS_STATUS_E_NOMEM;
+ }
+
+ vos_mem_zero(status_info, sizeof(*status_info));
+
+ wda_params = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ;
+ if(NULL == wda_params)
+ {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: VOS MEM Alloc Failure", __func__);
+ VOS_ASSERT(0);
+ vos_mem_free(status_info);
+ vos_mem_free(mdns_info);
+ return VOS_STATUS_E_NOMEM;
+ }
+
+ status_info->bss_idx = mdns_info->bss_idx;
+
+ wda_params->pWdaContext = wda_handle;
+ wda_params->wdaMsgParam = mdns_info;
+ wda_params->wdaWdiApiMsgParam = (void *)status_info;
+
+ wstatus = wdi_get_mdns_stats_req(status_info,
+ (wdi_get_stats_rsp_cb)
+ wda_get_stats_rsp_callback,
+ wda_params);
+ if(IS_WDI_STATUS_FAILURE(wstatus))
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "Failed to send wdi_set_mdns_response_req cmd" );
+ status = CONVERT_WDI2VOS_STATUS(wstatus);
+ vos_mem_free(wda_params->wdaWdiApiMsgParam) ;
+ vos_mem_free(wda_params->wdaMsgParam);
+ vos_mem_free(wda_params);
+ }
+
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "Get mDNS stats");
+ return status;
+}
+#endif /* MDNS_OFFLOAD */
+
/*
* FUNCTION: WDA_McProcessMsg
* Trigger DAL-AL to start CFG download
@@ -16200,26 +17256,16 @@ VOS_STATUS WDA_McProcessMsg( v_CONTEXT_t pVosContext, vos_msg_t *pMsg )
/* timer related messages */
case WDA_TIMER_BA_ACTIVITY_REQ:
{
- WDA_BaCheckActivity(pWDA, false);
+ WDA_BaCheckActivity(pWDA) ;
break ;
}
+
/* timer related messages */
case WDA_TIMER_TRAFFIC_STATS_IND:
{
WDA_TimerTrafficStatsInd(pWDA);
break;
}
- /* Connection status related messages */
- case WDA_TRIGGER_ADD_BA_REQ:
- {
- WDA_BaCheckActivity(pWDA, true);
- break;
- }
- case WDA_GET_CON_STATUS:
- {
- WDA_GetConnectionStatus(pWDA, (getConStatusParams *)pMsg->bodyptr);
- break;
- }
#ifdef WLAN_FEATURE_VOWIFI_11R
case WDA_AGGR_QOS_REQ:
{
@@ -16513,7 +17559,32 @@ VOS_STATUS WDA_McProcessMsg( v_CONTEXT_t pVosContext, vos_msg_t *pMsg )
WDA_ProcessEncryptMsgReq(pWDA, (u8 *)pMsg->bodyptr);
break;
}
-
+#ifdef DHCP_SERVER_OFFLOAD
+ case WDA_SET_DHCP_SERVER_OFFLOAD_REQ:
+ {
+ wda_process_dhcpserver_offload_req(pWDA,
+ (sir_dhcp_srv_offload_info_t *)pMsg->bodyptr);
+ break;
+ }
+#endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+ case WDA_SET_MDNS_OFFLOAD_CMD:
+ wda_set_mdns_offload_req(pWDA,
+ (sir_mdns_offload_info_t *)pMsg->bodyptr);
+ break;
+ case WDA_SET_MDNS_FQDN_CMD:
+ wda_set_mdns_fqdn_req(pWDA,
+ (sir_mdns_fqdn_info_t *)pMsg->bodyptr);
+ break;
+ case WDA_SET_MDNS_RESPONSE_CMD:
+ wda_set_mdns_response_req(pWDA,
+ (sir_mdns_resp_info_t *)pMsg->bodyptr);
+ break;
+ case WDA_GET_MDNS_STATUS_CMD:
+ wda_get_mdns_stats_req(pWDA,
+ (sir_get_mdns_stats_info_t *) pMsg->bodyptr);
+ break;
+#endif /* MDNS_OFFLOAD */
case WDA_NAN_REQUEST:
{
WDA_ProcessNanRequest( pWDA, (tNanRequest *)pMsg->bodyptr);
@@ -16576,6 +17647,44 @@ VOS_STATUS WDA_McProcessMsg( v_CONTEXT_t pVosContext, vos_msg_t *pMsg )
WDA_ProcessTLPauseInd(pWDA, pMsg->bodyval);
break;
}
+#ifdef WLAN_FEATURE_APFIND
+ case WDA_APFIND_SET_CMD:
+ {
+ WDA_Process_apfind_set_cmd(pWDA,
+ (struct hal_apfind_request *)pMsg->bodyptr);
+ }
+#endif
+#ifdef SAP_AUTH_OFFLOAD
+ case WDA_SET_SAP_AUTH_OFL:
+ {
+ wda_process_sap_auth_offload(pWDA,
+ (struct tSirSapOffloadInfo*)pMsg->bodyptr);
+ break;
+ }
+ case WDA_SAP_OFL_ADD_STA:
+ {
+ WDA_ProcessSapAuthOffloadAddStaReq(pWDA,
+ (tAddStaParams *)pMsg->bodyptr);
+ break;
+ }
+ case WDA_SAP_OFL_DEL_STA:
+ {
+ WDA_ProcessSapAuthOffloadDelStaReq(pWDA,
+ (tDeleteStaParams *)pMsg->bodyptr);
+ break;
+ }
+#endif
+ case WDA_CAP_TSF_REQ:
+ {
+ WDA_ProcessCapTsfReq(pWDA, (tSirCapTsfParams *)
+ pMsg->bodyptr);
+ break;
+ }
+ case WDA_GET_TSF_REQ:
+ {
+ WDA_ProcessGetTsfReq(pWDA, (tSirCapTsfParams *)pMsg->bodyptr);
+ break;
+ }
case WDA_SET_ARP_STATS_REQ:
{
WDA_ProcessSetARPStatsReq(pWDA, (setArpStatsParams *)pMsg->bodyptr);
@@ -16670,6 +17779,13 @@ void WDA_lowLevelIndCallback(WDI_LowLevelIndType *wdiLowLevelInd,
WDA_SendMsg(pWDA, WDA_MISSED_BEACON_IND, (void *)pMissBeacInd , 0) ;
break ;
}
+#ifdef WLAN_FEATURE_APFIND
+ case WDI_AP_FOUND_IND:
+ {
+ WDA_SendMsg(pWDA, WDA_AP_FIND_IND, NULL, 0) ;
+ break ;
+ }
+#endif
case WDI_UNKNOWN_ADDR2_FRAME_RX_IND:
{
/* TODO: Decode Ind and send Ind to PE */
@@ -17926,55 +19042,19 @@ bool WDA_AllowAddBA(tpAniSirGlobal pMac, tANI_U8 staId, tANI_U8 tid)
return true;
}
-void WDA_GetConnectionStatus(tWDA_CbContext *pWDA,
- getConStatusParams *conStatusParams)
-{
- tpAniSirGlobal pMac;
- uint8_t sta_id, tid;
- bool tx_aggr;
- bool status = false;
-
- pMac = (tpAniSirGlobal)VOS_GET_MAC_CTXT(pWDA->pVosContext);
- if (NULL == pMac)
- {
- VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
- "%s: pMac is NULL",__func__);
- return;
- }
-
- tx_aggr= pMac->lim.test_status_bainfo.tx_aggr;
- sta_id = pMac->lim.test_status_bainfo.sta_id;
- tid = pMac->lim.test_status_bainfo.tid;
-
- if (tx_aggr && WDA_GET_BA_TXFLAG(pWDA, sta_id, tid))
- status = true;
-
- if (conStatusParams->rsp_cb_fn)
- conStatusParams->rsp_cb_fn(conStatusParams->data_ctx, status);
-}
-
-static void WDA_StoreTestBAInfo(tpAniSirGlobal pMac, bool tx_aggr,
- uint8_t sta_id, uint8_t tid)
-{
- pMac->lim.test_status_bainfo.tx_aggr = tx_aggr;
- pMac->lim.test_status_bainfo.sta_id= sta_id;
- pMac->lim.test_status_bainfo.tid = tid;
-}
-
/*
* BA Activity check timer handler
*/
-void WDA_BaCheckActivity(tWDA_CbContext *pWDA, bool test_con)
+void WDA_BaCheckActivity(tWDA_CbContext *pWDA)
{
tANI_U8 curSta = 0 ;
tANI_U8 tid = 0 ;
tANI_U8 size = 0 ;
tANI_U8 baCandidateCount = 0 ;
tANI_U8 newBaCandidate = 0 ;
- tANI_U32 val;
+ tANI_U32 val, val1;
WDI_TriggerBAReqCandidateType baCandidate[WDA_MAX_STA] = {{0}} ;
tpAniSirGlobal pMac;
- bool found = false;
if (NULL == pWDA)
{
@@ -18014,16 +19094,18 @@ void WDA_BaCheckActivity(tWDA_CbContext *pWDA, bool test_con)
val = 0;
}
+ if (wlan_cfgGetInt(pMac,
+ WNI_CFG_ENABLE_TX_RX_AGGREGATION, &val1) !=
+ eSIR_SUCCESS)
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "Unable to get WNI_CFG_ENABLE_TX_RX_AGGREGATION");
+ val1 = 1;
+ }
/* walk through all STA entries and find out TX packet count */
for(curSta = 0 ; curSta < pWDA->wdaMaxSta ; curSta++)
{
tANI_U32 currentOperChan = pWDA->wdaStaInfo[curSta].currentOperChan;
- WLANTL_STAStateType tlSTAState;
- tANI_U8 validStaIndex = pWDA->wdaStaInfo[curSta].ucValidStaIndex;
-
- if (found)
- break;
-
#ifdef WLAN_SOFTAP_VSTA_FEATURE
// We can only do BA on "hard" STAs.
if (!(IS_HWSTA_IDX(curSta)))
@@ -18031,47 +19113,47 @@ void WDA_BaCheckActivity(tWDA_CbContext *pWDA, bool test_con)
continue;
}
#endif //WLAN_SOFTAP_VSTA_FEATURE
-
- if (!((WDA_VALID_STA_INDEX == validStaIndex) &&
- (VOS_STATUS_SUCCESS == WDA_TL_GET_STA_STATE(pWDA->pVosContext,
- curSta, &tlSTAState))))
- continue;
-
- if (WLANTL_STA_AUTHENTICATED != tlSTAState)
- continue;
-
- if(val && ((currentOperChan >= SIR_11B_CHANNEL_BEGIN) &&
- (currentOperChan <= SIR_11B_CHANNEL_END))) {
- VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
- "%s: BTC disabled aggregation - dont start"
- "TX ADDBA req",__func__);
- continue;
- }
-
for(tid = 0 ; tid < STACFG_MAX_TC ; tid++)
{
+ WLANTL_STAStateType tlSTAState ;
tANI_U32 txPktCount = 0 ;
- if (VOS_STATUS_SUCCESS == WDA_TL_GET_TX_PKTCOUNT( pWDA->pVosContext,
- curSta, tid, &txPktCount))
+ tANI_U8 validStaIndex = pWDA->wdaStaInfo[curSta].ucValidStaIndex ;
+ if((WDA_VALID_STA_INDEX == validStaIndex) &&
+ (VOS_STATUS_SUCCESS == WDA_TL_GET_STA_STATE( pWDA->pVosContext,
+ curSta, &tlSTAState)) &&
+ (VOS_STATUS_SUCCESS == WDA_TL_GET_TX_PKTCOUNT( pWDA->pVosContext,
+ curSta, tid, &txPktCount)))
{
- if(!WDA_GET_BA_TXFLAG(pWDA, curSta, tid) &&
- WDA_AllowAddBA(pMac, curSta, tid) &&
- (((eSYSTEM_STA_IN_IBSS_ROLE == pWDA->wdaGlobalSystemRole)
- && txPktCount) ||
- (txPktCount >= WDA_LAST_POLLED_THRESHOLD(pWDA, curSta, tid)) ||
- test_con))
+#if 0
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO_LOW,
+ "************* %d:%d, %d ",curSta, txPktCount,
+ pWDA->wdaStaInfo[curSta].framesTxed[tid]);
+#endif
+ if(val && ( (currentOperChan >= SIR_11B_CHANNEL_BEGIN) &&
+ (currentOperChan <= SIR_11B_CHANNEL_END)))
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "%s: BTC disabled aggregation - dont start "
+ "TX ADDBA req",__func__);
+ }
+ else if (!val1)
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "%s: aggregation disabled- dont start "
+ "TX ADDBA req",__func__);
+ }
+ else if(!WDA_GET_BA_TXFLAG(pWDA, curSta, tid)
+ && (WLANTL_STA_AUTHENTICATED == tlSTAState)
+ && WDA_AllowAddBA(pMac, curSta, tid)
+ && (((eSYSTEM_STA_IN_IBSS_ROLE ==
+ pWDA->wdaGlobalSystemRole) && txPktCount )
+ || (txPktCount >= WDA_LAST_POLLED_THRESHOLD(pWDA,
+ curSta, tid))))
{
/* get prepare for sending message to HAL */
//baCandidate[baCandidateCount].staIdx = curSta ;
baCandidate[baCandidateCount].ucTidBitmap |= 1 << tid ;
newBaCandidate = WDA_ENABLE_BA ;
-
- /* Trigger only one BA request to check connection status */
- if (test_con) {
- WDA_StoreTestBAInfo(pMac, true, curSta, tid);
- found = true;
- break;
- }
}
pWDA->wdaStaInfo[curSta].framesTxed[tid] = txPktCount ;
}
@@ -18140,14 +19222,6 @@ void WDA_BaCheckActivity(tWDA_CbContext *pWDA, bool test_con)
}
else
{
- if (test_con)
- {
- WDA_StoreTestBAInfo(pMac, false, pWDA->wdaMaxSta, STACFG_MAX_TC);
- VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
- "%s: ADDBA to test connection status no valid Tid found",
- __func__);
- }
-
VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO_LOW,
"There is no TID for initiating BA");
}
@@ -18167,7 +19241,6 @@ void WDA_BaCheckActivity(tWDA_CbContext *pWDA, bool test_con)
}
return ;
}
-
/*
* WDA common routine to create timer used by WDA.
*/
@@ -18251,7 +19324,6 @@ static VOS_STATUS wdaCreateTimers(tWDA_CbContext *pWDA)
}
return VOS_STATUS_SUCCESS ;
}
-
/*
* WDA common routine to destroy timer used by WDA.
*/
@@ -18860,6 +19932,8 @@ VOS_STATUS WDA_ProcessRoamScanOffloadReq(tWDA_CbContext *pWDA,
pRoamOffloadScanReqParams->nProbes;
pwdiRoamOffloadScanInfo->HomeAwayTime =
pRoamOffloadScanReqParams->HomeAwayTime;
+ pwdiRoamOffloadScanInfo->WeakZoneRssiThresholdForRoam =
+ pRoamOffloadScanReqParams->WeakZoneRssiThresholdForRoam;
pwdiRoamScanOffloadReqParams->wdiReqStatusCB = NULL;
/* Store Params pass it to WDI */
pWdaParams->wdaWdiApiMsgParam = (void *)pwdiRoamScanOffloadReqParams;
@@ -22177,5 +23251,274 @@ VOS_STATUS WDA_ProcessBcnMissPenaltyCount(tWDA_CbContext *pWDA,
vos_mem_free(params);
return CONVERT_WDI2VOS_STATUS(status) ;
}
-
#endif
+/*
+ * WDA_CapTsfRspCb : handle response for tsf requests
+ * @wdi_rsp : Response from WDI for tsf requests
+ * @user_data: pointer to user data
+ * Returns: None
+ */
+void WDA_CapTsfRspCb (wdi_cap_tsf_rsp_t *wdi_rsp, void *user_data)
+{
+
+ tWDA_ReqParams *wda_params = (tWDA_ReqParams *)user_data;
+ tSirCapTsfParams *cap_tsf_params;
+ struct stsf *stsf_temp;
+ VOS_STATUS status;
+
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "<------ %s " ,__func__);
+
+ if (NULL == wda_params) {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: pWdaParams received NULL", __func__);
+ VOS_ASSERT(0);
+ return;
+ }
+
+ if (NULL == wda_params->wdaMsgParam) {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: pWdaParams->wdaMsgParam is NULL", __func__);
+ VOS_ASSERT(0);
+ vos_mem_free(wda_params->wdaWdiApiMsgParam);
+ vos_mem_free(wda_params);
+ return;
+ }
+
+ stsf_temp = (struct stsf *)vos_mem_malloc(sizeof(*stsf_temp));
+ if (NULL == stsf_temp) {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: Unable to allocate tsf struct", __func__);
+ VOS_ASSERT(0);
+ vos_mem_free(wda_params->wdaWdiApiMsgParam);
+ vos_mem_free(wda_params->wdaMsgParam);
+ vos_mem_free(wda_params);
+ return;
+ }
+ cap_tsf_params = (tSirCapTsfParams *)wda_params->wdaMsgParam;
+ stsf_temp->session_id = cap_tsf_params->bss_idx;
+ stsf_temp->set_tsf_req = true;
+ stsf_temp->tsf_req_status = wdi_rsp->status;
+
+ if (cap_tsf_params->tsf_rsp_cb_func) {
+ cap_tsf_params->tsf_rsp_cb_func (
+ cap_tsf_params->tsf_rsp_cb_ctx, stsf_temp);
+ }
+ else {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: tsf callback is NULL", __func__);
+ vos_mem_free(stsf_temp);
+ }
+ status = CONVERT_WDI2VOS_STATUS(wdi_rsp->status);
+ if (status) {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: Capture TSF failed with status=%d", __func__,
+ status);
+ VOS_ASSERT(0);
+ }
+ vos_mem_free(wda_params->wdaWdiApiMsgParam);
+ vos_mem_free(wda_params->wdaMsgParam);
+ vos_mem_free(wda_params);
+ return;
+}
+
+/*
+ * WDA_GetTsfRspCb : handle response for get tsf request
+ * @wdi_rsp : Response from WDI for tsf requests
+ * @user_data: pointer to user data
+ * Returns: None
+ */
+void WDA_GetTsfRspCb (wdi_cap_tsf_rsp_t *wdi_rsp, void *user_data)
+{
+
+ tWDA_ReqParams *wda_params = (tWDA_ReqParams *)user_data;
+ tSirCapTsfParams *cap_tsf_params;
+ struct stsf *stsf_temp;
+ VOS_STATUS status;
+
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "<------ %s " ,__func__);
+
+ if (NULL == wda_params) {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: pWdaParams received NULL", __func__);
+ VOS_ASSERT(0);
+ return;
+ }
+
+ if (NULL == wda_params->wdaMsgParam) {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: pWdaParams->wdaMsgParam is NULL", __func__);
+ VOS_ASSERT(0);
+ vos_mem_free(wda_params->wdaWdiApiMsgParam);
+ vos_mem_free(wda_params);
+ return;
+ }
+
+ stsf_temp = (struct stsf *)vos_mem_malloc(sizeof(*stsf_temp));
+ if (NULL == stsf_temp) {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: Unable to allocate tsf struct", __func__);
+ VOS_ASSERT(0);
+ vos_mem_free(wda_params->wdaWdiApiMsgParam);
+ vos_mem_free(wda_params->wdaMsgParam);
+ vos_mem_free(wda_params);
+ return;
+ }
+ cap_tsf_params = (tSirCapTsfParams *)wda_params->wdaMsgParam;
+ stsf_temp->session_id = cap_tsf_params->bss_idx;
+ /* Indicate to upper layer that this is a get request */
+ stsf_temp->set_tsf_req = false;
+ stsf_temp->tsf_low = wdi_rsp->tsf_lo;
+ stsf_temp->tsf_high = wdi_rsp->tsf_hi;
+ stsf_temp->tsf_req_status = wdi_rsp->status;
+
+ if (cap_tsf_params->tsf_rsp_cb_func) {
+ cap_tsf_params->tsf_rsp_cb_func (
+ cap_tsf_params->tsf_rsp_cb_ctx, stsf_temp);
+ }
+ else {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: tsf callback is NULL", __func__);
+ vos_mem_free(stsf_temp);
+ }
+ status = CONVERT_WDI2VOS_STATUS(wdi_rsp->status);
+ if (status) {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: Capture TSF failed with status=%d", __func__,
+ status);
+ VOS_ASSERT(0);
+ }
+ vos_mem_free(wda_params->wdaWdiApiMsgParam);
+ vos_mem_free(wda_params->wdaMsgParam);
+ vos_mem_free(wda_params);
+ return;
+}
+/*
+ * FUNCTION: WDA_ProcessCapTsfReq
+ * Send capture tsf request to FW.
+ */
+VOS_STATUS WDA_ProcessCapTsfReq(tWDA_CbContext *pWDA, tSirCapTsfParams *params)
+{
+ WDI_Status status = WDI_STATUS_SUCCESS;
+ wdi_cap_tsf_params_t *pWDICapTsfReqType;
+ tWDA_ReqParams *pWdaParams ;
+
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "<------ %s " ,__func__);
+ if(NULL == params)
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: cap tsf params NULL", __func__);
+ VOS_ASSERT(0) ;
+ return -EINVAL;
+ }
+
+ pWDICapTsfReqType = (wdi_cap_tsf_params_t *)vos_mem_malloc(
+ sizeof(*pWDICapTsfReqType));
+ if(NULL == pWDICapTsfReqType)
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: VOS MEM Alloc Failure", __func__);
+ VOS_ASSERT(0);
+ vos_mem_free(params);
+ return VOS_STATUS_E_NOMEM;
+ }
+ pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(*pWdaParams)) ;
+ if(NULL == pWdaParams)
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: VOS MEM Alloc Failure", __func__);
+ VOS_ASSERT(0);
+ vos_mem_free(pWDICapTsfReqType);
+ vos_mem_free(params);
+ return VOS_STATUS_E_NOMEM;
+ }
+
+ pWDICapTsfReqType->bss_idx = params->bss_idx;
+ pWDICapTsfReqType->capTSFget = CAP_TSF_REQUEST;
+
+ pWdaParams->pWdaContext = pWDA;
+ pWdaParams->wdaMsgParam = params;
+ pWdaParams->wdaWdiApiMsgParam = (void *)pWDICapTsfReqType;
+
+ status = wdi_process_cap_tsf_req(pWDICapTsfReqType,
+ (wdi_tsf_rsp_cb)WDA_CapTsfRspCb,
+ pWdaParams);
+
+ if(IS_WDI_STATUS_FAILURE(status))
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "Failure in sendind WifiConfigReq, free all the memory" );
+ vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ;
+ vos_mem_free(pWdaParams->wdaMsgParam);
+ vos_mem_free(pWdaParams);
+ vos_mem_free(params);
+ }
+ return CONVERT_WDI2VOS_STATUS(status) ;
+}
+
+/*
+ * FUNCTION: WDA_ProcessGetTsfReq
+ * Send capture tsf request to FW.
+ */
+VOS_STATUS WDA_ProcessGetTsfReq(tWDA_CbContext *pWDA, tSirCapTsfParams *params)
+{
+ WDI_Status status = WDI_STATUS_SUCCESS;
+ wdi_cap_tsf_params_t *pWDIGetTsfReqType;
+ tWDA_ReqParams *pWdaParams ;
+
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "<------ %s " ,__func__);
+ if(NULL == params)
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: cap tsf params NULL", __func__);
+ VOS_ASSERT(0) ;
+ return VOS_STATUS_E_INVAL;
+ }
+
+ pWDIGetTsfReqType = (wdi_cap_tsf_params_t *)vos_mem_malloc(
+ sizeof(wdi_cap_tsf_params_t));
+ if(NULL == pWDIGetTsfReqType)
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: VOS MEM Alloc Failure", __func__);
+ VOS_ASSERT(0);
+ vos_mem_free(params);
+ return VOS_STATUS_E_INVAL;
+ }
+ pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ;
+ if(NULL == pWdaParams)
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: VOS MEM Alloc Failure", __func__);
+ VOS_ASSERT(0);
+ vos_mem_free(pWDIGetTsfReqType);
+ vos_mem_free(params);
+ return VOS_STATUS_E_NOMEM;
+ }
+
+ pWDIGetTsfReqType->bss_idx = params->bss_idx;
+ /* Indicate that this is a get request */
+ pWDIGetTsfReqType->capTSFget = GET_TSF_REQUEST;
+
+ pWdaParams->pWdaContext = pWDA;
+ pWdaParams->wdaMsgParam = params;
+ pWdaParams->wdaWdiApiMsgParam = (void *)pWDIGetTsfReqType;
+
+ status = wdi_process_get_tsf_req(pWDIGetTsfReqType,
+ (wdi_tsf_rsp_cb)WDA_GetTsfRspCb,
+ pWdaParams);
+
+ if(IS_WDI_STATUS_FAILURE(status))
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "Failure in sendind WifiConfigReq, free all the memory" );
+ vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ;
+ vos_mem_free(pWdaParams->wdaMsgParam);
+ vos_mem_free(pWdaParams);
+ vos_mem_free(params);
+ }
+ return CONVERT_WDI2VOS_STATUS(status) ;
+}
diff --git a/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi.h b/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi.h
index 65461f720c6..297fba64905 100644
--- a/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi.h
+++ b/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -430,6 +430,9 @@ typedef enum
#ifdef FEATURE_OEM_DATA_SUPPORT
WDI_START_OEM_DATA_RSP_IND_NEW,
#endif
+#ifdef WLAN_FEATURE_APFIND
+ WDI_AP_FOUND_IND,
+#endif
WDI_MAX_IND
}WDI_LowLevelIndEnumType;
@@ -3303,6 +3306,9 @@ typedef enum
WDI_LINK_FINISH_CAL_STATE = 13,
WDI_LINK_LISTEN_STATE = 14,
WDI_LINK_SEND_ACTION_STATE = 15,
+#ifdef WLAN_FEATURE_LFR_MBB
+ WDI_LINK_PRE_AUTH_REASSOC_STATE = 17,
+#endif
WDI_LINK_MAX = 0x7FFFFFFF
} WDI_LinkStateType;
@@ -5567,6 +5573,7 @@ typedef struct
WDI_MobilityDomainInfo MDID;
wpt_uint8 nProbes;
wpt_uint16 HomeAwayTime;
+ wpt_uint8 WeakZoneRssiThresholdForRoam;
} WDI_RoamOffloadScanInfo;
typedef struct
@@ -6416,6 +6423,157 @@ typedef struct
wpt_macAddr bssId;
}WDI_WifiConfigSetReqType;
+#ifdef DHCP_SERVER_OFFLOAD
+/**
+ * wdi_set_dhcp_server_offload_t - dhcp server offload info
+ * @bssidx: bss index
+ * @enable: enable od disable
+ * @srv_ipv4: server ip address
+ * @start_lsb: starting lsb addredd of pool
+ * @num_client: number of clients supported
+ */
+typedef struct {
+ wpt_uint8 bssidx;
+ wpt_uint32 enable;
+ wpt_uint32 srv_ipv4; /* server IP */
+ wpt_uint32 start_lsb; /* starting address assigned to client */
+ wpt_uint32 num_client; /* number of clients we support */
+} wdi_set_dhcp_server_offload_t;
+
+/**
+ * wdi_dhcp_server_offload_rsp_param_t - dhcp server offload response
+ * @status: status for the command success or failure
+ */
+typedef struct
+{
+ /* wdi status */
+ wpt_uint32 status;
+} wdi_dhcp_server_offload_rsp_param_t;
+#endif /* DHCP_SERVER_OFFLOAD */
+
+#ifdef MDNS_OFFLOAD
+/**
+ * The purpose of the multicast Domain Name System (mDNS) is to resolve host
+ * names to IP addresses within small networks that do not include a local
+ * name server. It utilizes essentially the same programming interfaces, packet
+ * formats and operating semantics as the unicast DNS, and the advantage is
+ * zero configuration service while no need for central or global server.
+ * Based on mDNS, the DNS-SD (Service Discovery) allows clients to discover a
+ * named list of services by type in a specified domain using standard
+ * DNS queries. Here, we provide the ability to advertise the available
+ * services by responding to mDNS queries.
+ */
+
+/**
+ * wdi_mdns_enable_offload_cmd_req - mdns enable request
+ * @bss_idx: bss index
+ * @enable: enable
+ */
+typedef struct {
+ wpt_uint8 bss_idx;
+ wpt_uint32 enable;
+} wdi_mdns_enable_offload_cmd_req;
+
+/**
+ * wdi_mdns_enable_offload_rsp_param_t - mDNS enable offload response
+ * @status: status for the command success or failure
+ */
+typedef struct
+{
+ wpt_uint32 status;
+} wdi_mdns_enable_offload_rsp_param_t;
+
+#define WMI_MAX_MDNS_FQDN_LEN 64
+#define WMI_MAX_MDNS_RESP_LEN 512
+#define WMI_MDNS_FQDN_TYPE_GENERAL 0
+#define WMI_MDNS_FQDN_TYPE_UNIQUE 1
+
+/**
+ * wdi_mdns_set_fqdn_cmd_req - set fqdn request
+ * @bss_idx: bss index
+ * @type: type of fqdn, general or unique
+ * @fqdn_len: length of fqdn
+ * @fqdn_data: TLV byte stream of fqdn data of length fqdn_len fully-qualified
+ * domain name to check if match with the received queries
+ */
+typedef struct {
+ wpt_uint8 bss_idx;
+ wpt_uint32 type;
+ wpt_uint32 fqdn_len;
+ wpt_uint8 fqdn_data[WMI_MAX_MDNS_FQDN_LEN];
+} wdi_mdns_set_fqdn_cmd_req;
+
+/**
+ * wdi_mdns_set_fqdn_rsp_param_t - mDNS set fqdn response
+ * @status: status for the command success or failure
+ */
+typedef struct
+{
+ wpt_uint32 status;
+} wdi_mdns_set_fqdn_rsp_param_t;
+
+/**
+ * wdi_mdns_set_resp_req - mDNS response request
+ * @bss_idx: bss index
+ * @ar_count: Answer Resource Record count
+ * @resp_len: length of response
+ * @resp_data: TLV byte stream of resp data of length resp_len responses consisits of Resource Records
+ */
+typedef struct {
+ wpt_uint8 bss_idx;
+ wpt_uint32 ar_count;
+ wpt_uint32 resp_len;
+ wpt_uint8 resp_data[WMI_MAX_MDNS_RESP_LEN];
+} wdi_mdns_set_resp_req;
+
+/**
+ * wdi_mdns_set_rsp_param_t - mDNS set response rsp
+ * @status: status for the command success or failure
+ */
+typedef struct
+{
+ wpt_uint32 status;
+} wdi_mdns_set_rsp_param_t;
+
+/**
+ * wdi_mdns_get_stats_req - get mdns stats request
+ * @bss_idx: bss index
+ */
+typedef struct {
+ wpt_uint8 bss_idx;
+} wdi_mdns_get_stats_req;
+
+/**
+ * wdi_mdns_stats_rsp_t - mdns stats
+ * @bss_idx: bss index
+ * @current_ts: curTimestamp in milliseconds
+ * @last_querry_ts: last received Query in milliseconds
+ * @last_resp_ts: last sent Response in milliseconds
+ * @tot_queries: stats of received queries
+ * @tot_matches: stats of macth queries
+ * @tot_rsp: stats of responses
+ * @status: indicate the current status of mDNS offload
+ */
+typedef struct {
+ wpt_uint8 bss_idx;
+ wpt_uint32 current_ts;
+ wpt_uint32 last_querry_ts;
+ wpt_uint32 last_resp_ts;
+ wpt_uint32 tot_queries;
+ wpt_uint32 tot_matches;
+ wpt_uint32 tot_rsp;
+ wpt_uint32 status;
+} wdi_mdns_stats_rsp_param_t;
+#endif /* MDNS_OFFLOAD */
+
+#ifdef WLAN_FEATURE_APFIND
+struct WDI_APFind_cmd
+{
+ wpt_uint32 data_len;
+ wpt_uint8 data[];
+};
+#endif
+
/**
* struct WDI_FwrMemDumpReqType - firmware memory dump request details.
.*.@FWMemDumpReqCb - Associated Callback
@@ -6464,6 +6622,50 @@ struct WDI_AllowedActionFramesInd {
wpt_uint32 bitmask;
wpt_uint32 reserved;
};
+
+struct WDI_sap_ofl_enable_params{
+
+ wpt_macAddr macAddr;
+ /** enable/disable sap auth offload */
+ wpt_uint32 enable;
+ /** authentication mode (defined above) */
+ wpt_uint32 rsn_authmode;
+ /** unicast cipher set */
+ wpt_uint32 rsn_ucastcipherset;
+ /** mcast/group cipher set */
+ wpt_uint32 rsn_mcastcipherset;
+ /** mcast/group management frames cipher set */
+ wpt_uint32 rsn_mcastmgmtcipherset;
+ /** sap channel */
+ wpt_uint32 channel;
+ /** length of psk */
+ wpt_uint32 psk_len;
+ wpt_uint8 key[64];
+};
+
+/**
+ * wdi_cap_tsf_params_t - wdi capture tsf params
+ * @bssidx: bss index
+ * @capTSFget: whether get/set request
+ *
+ */
+ typedef struct {
+ wpt_uint8 bss_idx;
+ wpt_uint8 capTSFget;
+} wdi_cap_tsf_params_t;
+
+/**
+ * wdi_cap_tsf_rsp_t - capture tsf response
+ * @bssidx: bss index
+ * @capTSFget: whether get/set request
+ *
+ */
+ typedef struct {
+ wpt_uint32 status;
+ wpt_uint32 tsf_lo;
+ wpt_uint32 tsf_hi;
+} wdi_cap_tsf_rsp_t;
+
/*----------------------------------------------------------------------------
* WDI callback types
*--------------------------------------------------------------------------*/
@@ -8425,6 +8627,19 @@ typedef void (*WDI_AntennaDivSelRspCb)(WDI_Status status,
typedef void (*wdi_nud_set_arp_rsp_cb)(void *event_data,void *user_data);
typedef void (*wdi_nud_get_arp_rsp_cb)(void *event_data,void *user_data);
+#ifdef DHCP_SERVER_OFFLOAD
+typedef void (*wdi_dhcp_srv_offload_rsp_cb)(void *event_data,void *user_data);
+#endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+typedef void (*wdi_mdns_enable_rsp_cb)(void *event_data,void *user_data);
+typedef void (*wdi_mdns_fqdn_rsp_cb)(void *event_data,void *user_data);
+typedef void (*wdi_mdns_resp_rsp_cb)(void *event_data,void *user_data);
+typedef void (*wdi_get_stats_rsp_cb)(void *event_data,void *user_data);
+#endif /* MDNS_OFFLOAD */
+
+typedef void (*wdi_tsf_rsp_cb)(void *event_data,void *user_data);
+
+
/*========================================================================
* Function Declarations and Documentation
==========================================================================*/
@@ -12229,4 +12444,67 @@ WDI_GetARPStatsReq
WDI_GetARPStatsRspCb wdiGetARPStatsRspCb,
void* pUserData
);
+
+WDI_Status
+WDI_process_sap_auth_offload(
+ struct WDI_sap_ofl_enable_params *sap_ofl_enable_cmd
+);
+#ifdef WLAN_FEATURE_APFIND
+WDI_Status WDI_process_ap_find_cmd(struct WDI_APFind_cmd *params);
+#endif
+#ifdef DHCP_SERVER_OFFLOAD
+WDI_Status
+wdi_process_dhcpserver_offload_req
+(
+ wdi_set_dhcp_server_offload_t *dhcp_info,
+ wdi_dhcp_srv_offload_rsp_cb wdi_dhcp_srv_offload_rsp_callback,
+ void *user_data
+);
+#endif /* DHCP_SERVER_OFFLOAD */
+
+#ifdef MDNS_OFFLOAD
+WDI_Status
+wdi_set_mdns_offload_req
+(
+ wdi_mdns_enable_offload_cmd_req *mdns_info,
+ wdi_mdns_enable_rsp_cb wdi_mdns_enable_rsp_callback,
+ void *user_data
+);
+
+WDI_Status
+wdi_set_mdns_fqdn_req
+(
+ wdi_mdns_set_fqdn_cmd_req *mdns_info,
+ wdi_mdns_fqdn_rsp_cb wdi_mdns_fqdn_rsp_callback,
+ void *user_data
+);
+
+WDI_Status
+wdi_set_mdns_response_req
+(
+ wdi_mdns_set_resp_req *mdns_info,
+ wdi_mdns_resp_rsp_cb wdi_mdns_resp_rsp_callback,
+ void *user_data
+);
+
+WDI_Status
+wdi_get_mdns_stats_req
+(
+ wdi_mdns_get_stats_req *mdns_info,
+ wdi_get_stats_rsp_cb wdi_get_stats_rsp_callback,
+ void *user_data
+);
+#endif /* MDNS_OFFLOAD */
+
+WDI_Status
+wdi_process_cap_tsf_req (wdi_cap_tsf_params_t *wdi_cap_tsf_req,
+ wdi_tsf_rsp_cb wdi_tsf_rsp_callback,
+ void *user_data);
+
+WDI_Status
+wdi_process_get_tsf_req (wdi_cap_tsf_params_t *wdi_get_tsf_req,
+ wdi_tsf_rsp_cb wdi_tsf_rsp_callback,
+ void *user_data);
+
+
#endif /* #ifndef WLAN_QCT_WDI_H */
diff --git a/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_bd.h b/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_bd.h
index c828c4b2ea5..4ca3a656472 100644
--- a/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_bd.h
+++ b/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_bd.h
@@ -325,9 +325,16 @@ typedef struct
this field is set to zero. */
wpt_uint32 tid:4;
- wpt_uint32 reserved4:8;
+ wpt_uint32 indType:2;
+ wpt_uint32 reserved4:4;
+ wpt_uint32 htt_t2h_msg:1;
+ wpt_uint32 fc:1;
+
#else
- wpt_uint32 reserved4:8;
+ wpt_uint32 fc:1;
+ wpt_uint32 htt_t2h_msg:1;
+ wpt_uint32 reserved4:4;
+ wpt_uint32 indType:2;
wpt_uint32 tid:4;
#ifdef WCN_PRONTO
wpt_uint32 rxDXEPriorityRouting:1;
diff --git a/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_dp.h b/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_dp.h
index 85446f1b6dd..ca1b403af0f 100644
--- a/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_dp.h
+++ b/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_dp.h
@@ -226,6 +226,8 @@ when who what, where, why
#endif
+#define WDI_RXBD_MLME_STA_STATUS 0x1
+#define WDI_RXBD_SAP_TX_STATS 0x2
/*--------------------------------------------------------------------------
BD header macros - used by the data path to get or set various values
inside the packet BD
@@ -312,6 +314,8 @@ when who what, where, why
#define WDI_RX_BD_GET_EXTSCANFULLSCANRESIND( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->extscanBuffer)
#endif
+#define WDI_RX_BD_GET_PER_SAPOFFLOAD( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->indType)
+
/*------------ RSSI and SNR Information extraction -------------*/
#define WDI_RX_BD_GET_RSSI0( _pvBDHeader ) \
(((((WDI_RxBdType*)_pvBDHeader)->phyStats0) >> 24) & 0xff)
diff --git a/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_i.h b/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_i.h
index d0faaf04697..5fb24ba0722 100644
--- a/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_i.h
+++ b/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_i.h
@@ -491,9 +491,19 @@ typedef enum
WDI_PER_ROAM_SCAN_OFFLOAD_REQ = 116,
WDI_PER_ROAM_SCAN_TRIGGER_REQ = 117,
#endif
-/* ARP DEBUG STATS */
- WDI_FW_ARP_STATS_REQ = 118,
- WDI_FW_GET_ARP_STATS_REQ = 119,
+
+ WDI_DHCP_SERVER_OFFLOAD_REQ = 118,
+ WDI_MDNS_ENABLE_OFFLOAD_REQ = 119,
+ WDI_MDNS_FQDN_OFFLOAD_REQ = 120,
+ WDI_MDNS_RESP_OFFLOAD_REQ = 121,
+ WDI_MDNS_STATS_OFFLOAD_REQ = 122,
+
+ WDI_CAP_TSF_REQ = 123,
+ WDI_GET_TSF_REQ = 124,
+
+ /* ARP DEBUG STATS */
+ WDI_FW_ARP_STATS_REQ = 125,
+ WDI_FW_GET_ARP_STATS_REQ = 126,
WDI_MAX_REQ,
@@ -558,8 +568,12 @@ typedef enum
WDI_ANTENNA_DIVERSITY_SELECTION_REQ = WDI_MAX_REQ + 21,
WDI_MODIFY_ROAM_PARAMS_IND = WDI_MAX_REQ + 22,
WDI_SET_ALLOWED_ACTION_FRAMES_IND = WDI_MAX_REQ + 23,
+#ifdef SAP_AUTH_OFFLOAD
+ WDI_PROCESS_SAP_AUTH_OFFLOAD_IND = WDI_MAX_REQ +24,
+#endif
- WDI_MAX_UMAC_IND = WDI_MAX_REQ + 24
+ WDI_SET_AP_FIND_IND = WDI_MAX_REQ + 25,
+ WDI_MAX_UMAC_IND = WDI_MAX_REQ + 26
}WDI_RequestEnumType;
@@ -869,8 +883,15 @@ typedef enum
WDI_PER_ROAM_SCAN_OFFLOAD_RSP = 116,
WDI_PER_ROAM_SCAN_TRIGGER_RSP = 117,
#endif
- WDI_FW_ARP_STATS_RSP = 118,
- WDI_FW_GET_ARP_STATS_RSP = 119,
+ WDI_DHCP_SERVER_OFFLOAD_RSP = 118,
+ WDI_MDNS_ENABLE_OFFLOAD_RSP = 119,
+ WDI_MDNS_FQDN_OFFLOAD_RSP = 120,
+ WDI_MDNS_RESP_OFFLOAD_RSP = 121,
+ WDI_MDNS_STATS_OFFLOAD_RSP = 122,
+ WDI_CAPTURE_GET_TSF_TSTAMP_RSP = 123,
+ WDI_FW_ARP_STATS_RSP = 124,
+ WDI_FW_GET_ARP_STATS_RSP = 125,
+
/*-------------------------------------------------------------------------
Indications
@@ -962,6 +983,9 @@ typedef enum
WDI_HAL_RSSI_BREACHED_IND = WDI_HAL_IND_MIN + 32,
WDI_HAL_START_OEM_DATA_RSP_IND_NEW = WDI_HAL_IND_MIN + 33,
WDI_ANTENNA_DIVERSITY_SELECTION_RSP = WDI_HAL_IND_MIN + 34,
+#ifdef WLAN_FEATURE_APFIND
+ WDI_HAL_QRF_PREF_NETWORK_FOUND_IND = WDI_HAL_IND_MIN + 35,
+#endif
WDI_MAX_RESP
}WDI_ResponseEnumType;
@@ -1327,6 +1351,8 @@ typedef struct
wpt_uint8 roamDelayStatsEnabled;
/* enable/disable sendMgmtPktViaWQ5 params in ini */
wpt_boolean sendMgmtPktViaWQ5;
+ /* Wake lock for keep device in awake once host gets a find AP indication */
+ vos_wake_lock_t find_ap_lock;
}WDI_ControlBlockType;
@@ -5914,6 +5940,15 @@ WDI_Status WDI_ProcessLphbCfgRsp
);
#endif /* FEATURE_WLAN_LPHB */
+#ifdef WLAN_FEATURE_APFIND
+WDI_Status
+WDI_ProcessQRFPrefNetworkFoundInd
+(
+ WDI_ControlBlockType* pWDICtx,
+ WDI_EventInfoType* pEventData
+);
+#endif
+
/**
@brief Process Rate Update Indication and post it to HAL
@@ -6640,6 +6675,131 @@ WDI_ProcessSetAllowedActionFramesInd
WDI_ControlBlockType* pWDICtx,
WDI_EventInfoType* pEventData
);
+#ifdef SAP_AUTH_OFFLOAD
+/**
+ * WDI_ProcessSapAuthOffloadInd - Process Set sap offload enable
+ * command
+ *
+ * @pWDICtx: pointer to the WLAN DAL context
+ * @pEventData: pointer to the event information structure
+ *
+ */
+WDI_Status
+WDI_ProcessSapAuthOffloadInd
+(
+ WDI_ControlBlockType* pWDICtx,
+ WDI_EventInfoType* pEventData
+ );
+#endif
+
+#ifdef DHCP_SERVER_OFFLOAD
+WDI_Status
+wdi_dhcp_server_offload_req
+(
+ WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data
+);
+
+WDI_Status
+wdi_dhcp_server_offload_rsp
+(
+ WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data
+);
+#endif /* DHCP_SERVER_OFFLOAD */
+
+#ifdef MDNS_OFFLOAD
+WDI_Status
+wdi_mdns_enable_offload_req
+(
+ WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data
+);
+
+WDI_Status
+wdi_mdns_enable_offload_rsp
+(
+ WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data
+);
+
+WDI_Status
+wdi_mdns_fqdn_offload_req
+(
+ WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data
+);
+
+WDI_Status
+wdi_mdns_fqdn_offload_rsp
+(
+ WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data
+);
+
+WDI_Status
+wdi_mdns_resp_offload_req
+(
+ WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data
+);
+
+WDI_Status
+wdi_mdns_resp_offload_rsp
+(
+ WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data
+);
+
+WDI_Status
+wdi_get_mdns_stats_offload_req
+(
+ WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data
+);
+
+WDI_Status
+wdi_get_mdns_stats_offload_rsp
+(
+ WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data
+);
+#endif /* MDNS_OFFLOAD */
+#ifdef WLAN_FEATURE_APFIND
+/**
+ * WDI_ProcessApFindInd - Process AP find command command
+ *
+ * @pWDICtx: pointer to the WLAN DAL context
+ * @pEventData: pointer to the event information structure
+ *
+ */
+WDI_Status
+WDI_ProcessApFindInd
+(
+ WDI_ControlBlockType* pWDICtx,
+ WDI_EventInfoType* pEventData
+);
+#endif
+
+WDI_Status
+wdi_cap_tsf_req
+(
+ WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data
+);
+
+WDI_Status
+wdi_get_tsf_req
+(
+ WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data
+);
+WDI_Status
+wdi_get_tsf_rsp
+(
+ WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data
+);
WDI_Status
WDI_ProcessSetArpStatsReq
@@ -6668,5 +6828,6 @@ WDI_ProcessGetArpStatsResp
WDI_ControlBlockType* pWDICtx,
WDI_EventInfoType* pEventData
);
+
#endif /*WLAN_QCT_WDI_I_H*/
diff --git a/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_sta.h b/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_sta.h
index 44cd97dc6f9..f62bbff6b80 100644
--- a/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_sta.h
+++ b/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_sta.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014, 2016 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -71,45 +71,6 @@ when who what, where, why
#define WDI_STA_INVALID_IDX 0xFF
/*----------------------------------------------------------------------------
- WDI_AddStaParams
- -------------------------------------------------------------------------*/
-typedef struct
-{
- wpt_uint8 ucSTAIdx;
- wpt_uint8 ucWmmEnabled;
- wpt_uint8 ucHTCapable;
-
- /* MAC Address of STA */
- wpt_macAddr staMacAddr;
-
- /*MAC Address of the BSS*/
- wpt_macAddr macBSSID;
-
- /* Field to indicate if this is sta entry for itself STA adding entry for itself
- or remote (AP adding STA after successful association.
- This may or may not be required in production driver.
- 0 - Self, 1 other/remote, 2 - bssid */
- wpt_uint8 ucStaType;
-
-
- /*DPU Information*/
- wpt_uint8 dpuIndex; // DPU table index
- wpt_uint8 dpuSig; // DPU signature
- wpt_uint8 bcastDpuIndex;
- wpt_uint8 bcastDpuSignature;
- wpt_uint8 bcastMgmtDpuIndex;
- wpt_uint8 bcastMgmtDpuSignature;
-
-
- /*RMF enabled/disabled*/
- wpt_uint8 ucRmfEnabled;
-
- /* Index into the BSS Session table */
- wpt_uint8 ucBSSIdx;
-
-}WDI_AddStaParams;
-
-/*----------------------------------------------------------------------------
WDI_StaStruct
-------------------------------------------------------------------------*/
typedef struct
@@ -206,41 +167,6 @@ WDI_STATableClose
WDI_ControlBlockType* pWDICtx
);
-
-/**
- @brief WDI_STATableAddSta - Function to Add Station
-
-
- @param pWDICtx: pointer to the WLAN DAL context
- pwdiParam: station parameters
-
- @see
- @return Result of the function call
-*/
-WDI_Status
-WDI_STATableAddSta
-(
- WDI_ControlBlockType* pWDICtx,
- WDI_AddStaParams* pwdiParam
-);
-
-/**
- @brief WDI_STATableDelSta - Function to Delete a Station
-
-
- @param pWDICtx: pointer to the WLAN DAL context
- ucSTAIdx: station to be deleted
-
- @see
- @return Result of the function call
-*/
-WDI_Status
-WDI_STATableDelSta
-(
- WDI_ControlBlockType* pWDICtx,
- wpt_uint8 ucSTAIdx
-);
-
/**
@brief WDI_STATableBSSDelSta - Function to Delete Stations in this BSS
@@ -356,25 +282,6 @@ WDI_STATableSetStaType
/**
- @brief WDI_STATableFindStaidByAddr - Given a station mac address, search
- for the corresponding station index from the Station Table.
-
- @param pWDICtx: WDI Context pointer
- staAddr: station address
- pucStaId: output station id
-
- @see
- @return Result of the function call
-*/
-WDI_Status
-WDI_STATableFindStaidByAddr
-(
- WDI_ControlBlockType* pWDICtx,
- wpt_macAddr staAddr,
- wpt_uint8* pucStaId
-);
-
-/**
@brief WDI_STATableGetStaAddr - get station address
@param pWDICtx: WDI Context pointer
diff --git a/drivers/staging/prima/CORE/WDI/CP/src/wlan_qct_wdi.c b/drivers/staging/prima/CORE/WDI/CP/src/wlan_qct_wdi.c
index 4dd8722b888..4aed25df745 100644
--- a/drivers/staging/prima/CORE/WDI/CP/src/wlan_qct_wdi.c
+++ b/drivers/staging/prima/CORE/WDI/CP/src/wlan_qct_wdi.c
@@ -90,6 +90,7 @@
#include "pttMsgApi.h"
#include "vos_trace.h"
+#include "vos_diag_core_event.h"
#include "vos_api.h"
@@ -220,10 +221,10 @@ static placeHolderInCapBitmap supportEnabledFeatures[] =
,WIFI_CONFIG //61
,ANTENNA_DIVERSITY_SELECTION //62
,PER_BASED_ROAMING //63
- ,FEATURE_NOT_SUPPORTED //64
- ,FEATURE_NOT_SUPPORTED //65
- ,FEATURE_NOT_SUPPORTED //66
- ,FEATURE_NOT_SUPPORTED //67
+ ,SAP_MODE_WOW //64
+ ,SAP_OFFLOADS //65
+ ,SAP_BUFF_ALLOC //66
+ ,MAKE_BEFORE_BREAK //67
,NUD_DEBUG //68
,FEATURE_NOT_SUPPORTED //69 reserved for FATAL_EVENT_LOGGING
,FEATURE_NOT_SUPPORTED //70 reserved for WIFI_DUAL_BAND_ENABLE
@@ -524,9 +525,27 @@ WDI_ReqProcFuncType pfnReqProcTbl[WDI_MAX_UMAC_IND] =
NULL,
NULL,
#endif /* WLAN_FEATURE_ROAM_SCAN_OFFLOAD */
+#ifdef DHCP_SERVER_OFFLOAD
+ wdi_dhcp_server_offload_req, /* WDI_DHCP_SERVER_OFFLOAD_REQ */
+#else
+ NULL,
+#endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+ wdi_mdns_enable_offload_req, /* WDI_MDNS_ENABLE_OFFLOAD_REQ */
+ wdi_mdns_fqdn_offload_req, /* WDI_MDNS_FQDN_OFFLOAD_REQ */
+ wdi_mdns_resp_offload_req, /* WDI_MDNS_RESP_OFFLOAD_REQ */
+ wdi_get_mdns_stats_offload_req, /* WDI_GET_MDNS_STATS_OFFLOAD_REQ */
+#else
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+#endif /* MDNS_OFFLOAD */
+ wdi_cap_tsf_req, /* WDI_CAP_TSF_REQ */
+ wdi_get_tsf_req, /* WDI_GET_TSF_REQ */
- WDI_ProcessSetArpStatsReq, /* WDI_FW_ARP_STATS_REQ */
- WDI_ProcessGetArpStatsReq, /* WDI_FW_GET_ARP_STATS_REQ */
+ WDI_ProcessSetArpStatsReq, /* WDI_FW_ARP_STATS_REQ */
+ WDI_ProcessGetArpStatsReq, /* WDI_FW_GET_ARP_STATS_REQ */
/*-------------------------------------------------------------------------
Indications
@@ -588,6 +607,12 @@ WDI_ReqProcFuncType pfnReqProcTbl[WDI_MAX_UMAC_IND] =
WDI_ProcessGetCurrentAntennaIndex, /* WDI_ANTENNA_DIVERSITY_SELECTION_REQ */
WDI_ProcessBcnMissPenaltyCount, /* WDI_MODIFY_ROAM_PARAMS_IND */
WDI_ProcessSetAllowedActionFramesInd, /* WDI_SET_ALLOWED_ACTION_FRAMES_IND */
+#ifdef SAP_AUTH_OFFLOAD
+ WDI_ProcessSapAuthOffloadInd, /* WDI_PROCESS_SAP_AUTH_OFFLOAD_IND */
+#endif
+#ifdef WLAN_FEATURE_APFIND
+ WDI_ProcessApFindInd, /* WDI_SET_AP_FIND_IND */
+#endif
};
@@ -849,9 +874,28 @@ WDI_RspProcFuncType pfnRspProcTbl[WDI_MAX_RESP] =
NULL,
NULL,
#endif
-/* ARP Debug Stats*/
+#ifdef DHCP_SERVER_OFFLOAD
+ wdi_dhcp_server_offload_rsp, /* WDI_DHCP_SERVER_OFFLOAD_RSP */
+#else
+ NULL,
+#endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+ wdi_mdns_enable_offload_rsp, /* WDI_MDNS_ENABLE_OFFLOAD_RSP */
+ wdi_mdns_fqdn_offload_rsp, /* WDI_MDNS_FQDN_OFFLOAD_RSP */
+ wdi_mdns_resp_offload_rsp, /* WDI_MDNS_RESP_OFFLOAD_RSP */
+ wdi_get_mdns_stats_offload_rsp, /* WDI_MDNS_STATS_OFFLOAD_RSP */
+#else
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+#endif /* MDNS_OFFLOAD */
+ wdi_get_tsf_rsp, /* WDI_CAPTURE_GET_TSF_TSTAMP_RSP */
+
+ /* ARP Debug Stats*/
WDI_ProcessSetArpStatsResp, /* WDI_FW_ARP_STATS_RSP */
WDI_ProcessGetArpStatsResp, /* WDI_FW_GET_ARP_STATS_RSP */
+
/*---------------------------------------------------------------------
Indications
---------------------------------------------------------------------*/
@@ -957,6 +1001,11 @@ WDI_RspProcFuncType pfnRspProcTbl[WDI_MAX_RESP] =
NULL,
#endif
WDI_ProcessGetCurrentAntennaIndexRsp, /* WDI_ANTENNA_DIVERSITY_SELECTION_RSP */
+#ifdef WLAN_FEATURE_APFIND
+ WDI_ProcessQRFPrefNetworkFoundInd, /* WDI_HAL_QRF_PREF_NETWORK_FOUND_IND */
+#else
+ NULL,
+#endif
};
@@ -1310,17 +1359,225 @@ static char *WDI_getReqMsgString(wpt_uint16 wdiReqMsgId)
CASE_RETURN_STRING( WDI_ANTENNA_DIVERSITY_SELECTION_REQ );
CASE_RETURN_STRING( WDI_MODIFY_ROAM_PARAMS_IND );
CASE_RETURN_STRING( WDI_SET_ALLOWED_ACTION_FRAMES_IND );
- CASE_RETURN_STRING( WDI_FW_ARP_STATS_REQ );
- CASE_RETURN_STRING( WDI_FW_GET_ARP_STATS_REQ );
+#ifdef SAP_AUTH_OFFLOAD
+ CASE_RETURN_STRING( WDI_PROCESS_SAP_AUTH_OFFLOAD_IND);
+#endif
+#ifdef DHCP_SERVER_OFFLOAD
+ CASE_RETURN_STRING( WDI_DHCP_SERVER_OFFLOAD_REQ );
+#endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+ CASE_RETURN_STRING( WDI_MDNS_ENABLE_OFFLOAD_REQ );
+ CASE_RETURN_STRING( WDI_MDNS_FQDN_OFFLOAD_REQ );
+ CASE_RETURN_STRING( WDI_MDNS_RESP_OFFLOAD_REQ );
+ CASE_RETURN_STRING( WDI_MDNS_STATS_OFFLOAD_REQ );
+#endif /* MDNS_OFFLOAD */
#ifdef WLAN_FEATURE_APFIND
CASE_RETURN_STRING( WDI_SET_AP_FIND_IND );
#endif
+ CASE_RETURN_STRING( WDI_FW_ARP_STATS_REQ );
+ CASE_RETURN_STRING( WDI_FW_GET_ARP_STATS_REQ );
+
default:
return "Unknown WDI MessageId";
}
}
+#ifdef DHCP_SERVER_OFFLOAD
+/**
+ * wdi_process_dhcpserver_offload_req() - wdi api to set dhcp server offload
+ * @dhcp_info: pointer to dhcp server offload
+ * @wdi_dhcp_srv_offload_rsp_callback: response callback
+ * @user_data: pointer to user data
+ *
+ * Return: WDI_Status
+ * WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status
+wdi_process_dhcpserver_offload_req
+(
+ wdi_set_dhcp_server_offload_t *dhcp_info,
+ wdi_dhcp_srv_offload_rsp_cb wdi_dhcp_srv_offload_rsp_callback,
+ void *user_data
+)
+{
+ WDI_EventInfoType wdi_event_data;
+
+ if ( eWLAN_PAL_FALSE == gWDIInitialized )
+ {
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+ "WDI API call before module is initialized - Fail request");
+ return WDI_STATUS_E_NOT_ALLOWED;
+ }
+
+ /*-------------------------------------------------------------------
+ Fill in Event data and post to the Main FSM
+ -----------------------------------------------------------------*/
+ wdi_event_data.wdiRequest = WDI_DHCP_SERVER_OFFLOAD_REQ;
+ wdi_event_data.pEventData = dhcp_info;
+ wdi_event_data.uEventDataSize = sizeof(*dhcp_info);
+ wdi_event_data.pCBfnc = wdi_dhcp_srv_offload_rsp_callback;
+ wdi_event_data.pUserData = user_data;
+
+ return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdi_event_data);
+}
+#endif /* DHCP_SERVER_OFFLOAD */
+
+#ifdef MDNS_OFFLOAD
+/**
+ * wdi_set_mdns_offload_req() - wdi api to set mdns enable offload
+ * @mdns_info: pointer to dhcp server offload
+ * @wdi_mdns_enable_offload_rsp_callback: response callback
+ * @user_data: pointer to user data
+ *
+ * Return: WDI_Status
+ * WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status
+wdi_set_mdns_offload_req
+
+(
+ wdi_mdns_enable_offload_cmd_req *mdns_info,
+ wdi_mdns_enable_rsp_cb wdi_mdns_enable_offload_rsp_callback,
+ void *user_data
+)
+{
+ WDI_EventInfoType wdi_event_data;
+
+ if ( eWLAN_PAL_FALSE == gWDIInitialized )
+ {
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+ "WDI API call before module is initialized - Fail request");
+ return WDI_STATUS_E_NOT_ALLOWED;
+ }
+
+ /*-------------------------------------------------------------------
+ Fill in Event data and post to the Main FSM
+ -----------------------------------------------------------------*/
+ wdi_event_data.wdiRequest = WDI_MDNS_ENABLE_OFFLOAD_REQ;
+ wdi_event_data.pEventData = mdns_info;
+ wdi_event_data.uEventDataSize = sizeof(*mdns_info);
+ wdi_event_data.pCBfnc = wdi_mdns_enable_offload_rsp_callback;
+ wdi_event_data.pUserData = user_data;
+
+ return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdi_event_data);
+}
+
+/**
+ * wdi_set_mdns_fqdn_req() - wdi api to set mdns fqdn request
+ * @fqdn_info: pointer to dhcp server offload
+ * @wdi_mdns_fqdn_offload_rsp_callback: response callback
+ * @user_data: pointer to user data
+ *
+ * Return: WDI_Status
+ * WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status
+wdi_set_mdns_fqdn_req
+
+(
+ wdi_mdns_set_fqdn_cmd_req *fqdn_info,
+ wdi_mdns_fqdn_rsp_cb wdi_mdns_fqdn_offload_rsp_callback,
+ void *user_data
+)
+{
+ WDI_EventInfoType wdi_event_data;
+
+ if ( eWLAN_PAL_FALSE == gWDIInitialized )
+ {
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+ "WDI API call before module is initialized - Fail request");
+ return WDI_STATUS_E_NOT_ALLOWED;
+ }
+
+ /*-------------------------------------------------------------------
+ Fill in Event data and post to the Main FSM
+ -----------------------------------------------------------------*/
+ wdi_event_data.wdiRequest = WDI_MDNS_FQDN_OFFLOAD_REQ;
+ wdi_event_data.pEventData = fqdn_info;
+ wdi_event_data.uEventDataSize = sizeof(*fqdn_info);
+ wdi_event_data.pCBfnc = wdi_mdns_fqdn_offload_rsp_callback;
+ wdi_event_data.pUserData = user_data;
+
+ return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdi_event_data);
+}
+
+/**
+ * wdi_set_mdns_response_req() - wdi api to mdns response
+ * @resp_info: pointer to mdns response
+ * @wdi_mdns_resp_offload_rsp_callback: response callback
+ * @user_data: pointer to user data
+ *
+ * Return: WDI_Status
+ * WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status
+wdi_set_mdns_response_req
+
+(
+ wdi_mdns_set_resp_req *resp_info,
+ wdi_mdns_resp_rsp_cb wdi_mdns_resp_offload_rsp_callback,
+ void *user_data
+)
+{
+ WDI_EventInfoType wdi_event_data;
+
+ if ( eWLAN_PAL_FALSE == gWDIInitialized )
+ {
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+ "WDI API call before module is initialized - Fail request");
+ return WDI_STATUS_E_NOT_ALLOWED;
+ }
+
+ /*-------------------------------------------------------------------
+ Fill in Event data and post to the Main FSM
+ -----------------------------------------------------------------*/
+ wdi_event_data.wdiRequest = WDI_MDNS_RESP_OFFLOAD_REQ;
+ wdi_event_data.pEventData = resp_info;
+ wdi_event_data.uEventDataSize = sizeof(*resp_info);
+ wdi_event_data.pCBfnc = wdi_mdns_resp_offload_rsp_callback;
+ wdi_event_data.pUserData = user_data;
+
+ return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdi_event_data);
+}
+
+/**
+ * wdi_get_mdns_stats_req() - wdi api to get mdns stats
+ * @stats_info: pointer to mdns stats info
+ * @wdi_get_stats_offload_rsp_callback: response callback
+ * @user_data: pointer to user data
+ *
+ * Return: WDI_Status
+ * WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status
+wdi_get_mdns_stats_req
+(
+ wdi_mdns_get_stats_req *stats_info,
+ wdi_get_stats_rsp_cb wdi_get_stats_offload_rsp_callback,
+ void *user_data
+)
+{
+ WDI_EventInfoType wdi_event_data;
+ if ( eWLAN_PAL_FALSE == gWDIInitialized )
+ {
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+ "WDI API call before module is initialized - Fail request");
+ return WDI_STATUS_E_NOT_ALLOWED;
+ }
+
+ /*-------------------------------------------------------------------
+ Fill in Event data and post to the Main FSM
+ -----------------------------------------------------------------*/
+ wdi_event_data.wdiRequest = WDI_MDNS_STATS_OFFLOAD_REQ;
+ wdi_event_data.pEventData = stats_info;
+ wdi_event_data.uEventDataSize = sizeof(*stats_info);
+ wdi_event_data.pCBfnc = wdi_get_stats_offload_rsp_callback;
+ wdi_event_data.pUserData = user_data;
+
+ return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdi_event_data);
+}
+#endif /* MDNS_OFFLOAD */
/**
* WDI_ProcessSetArpStatsResp() - WDI api to process set arp stats response
@@ -1400,6 +1657,7 @@ WDI_ProcessGetArpStatsResp
return WDI_STATUS_SUCCESS;
}
+
/**
@brief WDI_getRespMsgString prints the WDI resonse message in string.
@@ -1543,6 +1801,10 @@ static char *WDI_getRespMsgString(wpt_uint16 wdiRespMsgId)
CASE_RETURN_STRING (WDI_PER_ROAM_SCAN_OFFLOAD_RSP);
CASE_RETURN_STRING (WDI_PER_ROAM_SCAN_TRIGGER_RSP);
#endif
+#ifdef DHCP_SERVER_OFFLOAD
+ CASE_RETURN_STRING (WDI_DHCP_SERVER_OFFLOAD_RSP);
+#endif /* DHCP_SERVER_OFFLOAD */
+ CASE_RETURN_STRING (WDI_CAPTURE_GET_TSF_TSTAMP_RSP);
default:
return "Unknown WDI MessageId";
}
@@ -1734,6 +1996,29 @@ void WDI_TraceHostFWCapabilities(tANI_U32 *capabilityBitmap)
"%s", "PER_BASED_ROAMING");
pCapStr += strlen("PER_BASED_ROAMING");
break;
+ case SAP_MODE_WOW:
+ snprintf(pCapStr, sizeof("SAP_MODE_WOW"),
+ "%s", "SAP_MODE_WOW");
+ pCapStr += strlen("SAP_MODE_WOW");
+ break;
+ case SAP_OFFLOADS:
+ snprintf(pCapStr, sizeof("SAP_OFFLOADS"),
+ "%s", "SAP_OFFLOADS");
+ pCapStr += strlen("SAP_OFFLOADS");
+ break;
+
+ case SAP_BUFF_ALLOC:
+ snprintf(pCapStr, sizeof("SAP_BUFF_ALLOC"),
+ "%s", "SAP_BUFF_ALLOC");
+ pCapStr += strlen("SAP_BUFF_ALLOC");
+ break;
+
+ case MAKE_BEFORE_BREAK:
+ snprintf(pCapStr, sizeof("MAKE_BEFORE_BREAK"),
+ "%s", "MAKE_BEFORE_BREAK");
+ pCapStr += strlen("MAKE_BEFORE_BREAK");
+ break;
+
case NUD_DEBUG:
snprintf(pCapStr, sizeof("NUD_DEBUG"),
"%s", "NUD_DEBUG");
@@ -2058,7 +2343,6 @@ WDI_Init
goto fail_wdts_open;
}
}
-
/*The WDI is initialized - set state to init */
gWDICb.uGlobalState = WDI_INIT_ST;
gWDICb.roamDelayStatsEnabled = vos_get_roam_delay_stats_enabled();
@@ -2072,6 +2356,8 @@ WDI_Init
wdi_register_debug_callback();
+ vos_wake_lock_init(&gWDICb.find_ap_lock, "find_ap_lock");
+
return WDI_STATUS_SUCCESS;
/* ERROR handlers
@@ -2419,7 +2705,7 @@ WDI_Close
"Failed to delete mutex %d", wptStatus);
WDI_ASSERT(0);
}
-
+ vos_wake_lock_destroy(&gWDICb.find_ap_lock);
/*Clear control block. note that this will clear the "magic"
which will inhibit all asynchronous callbacks*/
WDI_CleanCB(&gWDICb);
@@ -2535,6 +2821,7 @@ WDI_Shutdown
"%s: Failed to delete mutex %d", __func__, wptStatus);
WDI_ASSERT(0);
}
+ vos_wake_lock_destroy(&gWDICb.find_ap_lock);
/* Free the global variables */
wpalMemoryFree(gpHostWlanFeatCaps);
wpalMemoryFree(gpFwWlanFeatCaps);
@@ -16911,12 +17198,6 @@ WDI_ProcessInitScanRsp
"Error returned WDI_ProcessInitScanRspi:%d BMPS%d",
wdiStatus, pWDICtx->bInBmps);
}
- else
- {
- WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
- "Error returned WDI_ProcessInitScanRspi:%d BMPS%d",
- wdiStatus, pWDICtx->bInBmps);
- }
/*Notify UMAC*/
wdiInitScanRspCb( wdiStatus, pWDICtx->pRspCBUserData);
@@ -23148,6 +23429,7 @@ WDI_SendIndication
*/
pWDICtx->wdiReqStatusCB( ((uStatus != eWLAN_PAL_STATUS_SUCCESS) && (uStatus != eWLAN_PAL_STATUS_E_RESOURCES)) ? WDI_STATUS_E_FAILURE: WDI_STATUS_SUCCESS,
pWDICtx->pReqStatusUserData);
+ pWDICtx->wdiReqStatusCB = NULL;
}
/*If sending of the message failed - it is considered catastrophic and
@@ -24560,6 +24842,8 @@ WDI_HAL_2_WDI_STATUS
/*The rest of the HAL error codes must be kept hidden from the UMAC as
they refer to specific internal modules of our device*/
default:
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+ "Fwr halStatus:%d", halStatus);
return WDI_STATUS_DEV_INTERNAL_FAILURE;
}
@@ -24887,12 +25171,36 @@ WDI_2_HAL_REQ_TYPE
return WLAN_HAL_MODIFY_ROAM_PARAMS_IND;
case WDI_SET_ALLOWED_ACTION_FRAMES_IND:
return WLAN_HAL_SET_ALLOWED_ACTION_FRAMES_IND;
+ case WDI_SET_AP_FIND_IND:
+ return WLAN_HAL_QRF_AP_FIND_COMMAND;
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
case WDI_PER_ROAM_SCAN_OFFLOAD_REQ:
return WLAN_HAL_SET_PER_ROAM_CONFIG_REQ;
case WDI_PER_ROAM_SCAN_TRIGGER_REQ:
return WLAN_HAL_PER_ROAM_SCAN_TRIGGER_REQ;
#endif
+#ifdef SAP_AUTH_OFFLOAD
+ case WDI_PROCESS_SAP_AUTH_OFFLOAD_IND:
+ return WLAN_HAL_SAP_AUTH_OFFLOAD_IND;
+#endif
+#ifdef DHCP_SERVER_OFFLOAD
+ case WDI_DHCP_SERVER_OFFLOAD_REQ:
+ return WLAN_HAL_DHCP_SERVER_OFFLOAD_REQ;
+#endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+ case WDI_MDNS_ENABLE_OFFLOAD_REQ:
+ return WLAN_HAL_MDNS_ENABLE_OFFLOAD_REQ;
+ case WDI_MDNS_FQDN_OFFLOAD_REQ:
+ return WLAN_HAL_MDNS_FQDN_OFFLOAD_REQ;
+ case WDI_MDNS_RESP_OFFLOAD_REQ:
+ return WLAN_HAL_MDNS_RESP_OFFLOAD_REQ;
+ case WDI_MDNS_STATS_OFFLOAD_REQ:
+ return WLAN_HAL_MDNS_STATS_OFFLOAD_REQ;
+#endif /* MDNS_OFFLOAD */
+ case WDI_CAP_TSF_REQ:
+ return WLAN_HAL_CAPTURE_GET_TSF_TSTAMP;
+ case WDI_GET_TSF_REQ:
+ return WLAN_HAL_CAPTURE_GET_TSF_TSTAMP;
case WDI_FW_ARP_STATS_REQ:
return WLAN_HAL_FW_SET_CLEAR_ARP_STATS_REQ;
case WDI_FW_GET_ARP_STATS_REQ:
@@ -25260,6 +25568,26 @@ case WLAN_HAL_DEL_STA_SELF_RSP:
case WLAN_HAL_PER_ROAM_SCAN_TRIGGER_RSP:
return WDI_PER_ROAM_SCAN_TRIGGER_RSP;
#endif
+#ifdef DHCP_SERVER_OFFLOAD
+ case WLAN_HAL_DHCP_SERVER_OFFLOAD_RSP:
+ return WDI_DHCP_SERVER_OFFLOAD_RSP;
+#endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+ case WLAN_HAL_MDNS_ENABLE_OFFLOAD_RSP:
+ return WDI_MDNS_ENABLE_OFFLOAD_RSP;
+ case WLAN_HAL_MDNS_FQDN_OFFLOAD_RSP:
+ return WDI_MDNS_FQDN_OFFLOAD_RSP;
+ case WLAN_HAL_MDNS_RESP_OFFLOAD_RSP:
+ return WDI_MDNS_RESP_OFFLOAD_RSP;
+ case WLAN_HAL_MDNS_STATS_OFFLOAD_RSP:
+ return WDI_MDNS_STATS_OFFLOAD_RSP;
+#endif /* MDNS_OFFLOAD */
+#ifdef WLAN_FEATURE_APFIND
+ case WLAN_HAL_QRF_PREF_NETW_FOUND_IND:
+ return WDI_HAL_QRF_PREF_NETWORK_FOUND_IND;
+#endif
+ case WLAN_HAL_CAPTURE_GET_TSF_TSTAMP_RSP:
+ return WDI_CAPTURE_GET_TSF_TSTAMP_RSP;
case WLAN_HAL_FW_SET_CLEAR_ARP_STATS_RSP:
return WDI_FW_ARP_STATS_RSP;
case WLAN_HAL_FW_GET_ARP_STATS_RSP:
@@ -25647,6 +25975,11 @@ WDI_2_HAL_LINK_STATE
case WDI_LINK_SEND_ACTION_STATE:
return eSIR_LINK_SEND_ACTION_STATE;
+#ifdef WLAN_FEATURE_LFR_MBB
+ case WDI_LINK_PRE_AUTH_REASSOC_STATE:
+ return eSIR_LINK_PRE_AUTH_REASSOC_STATE;
+#endif
+
default:
return eSIR_LINK_MAX;
}
@@ -26855,17 +27188,18 @@ WDI_ProcessSetPreferredNetworkReq
WDI_ASSERT(0);
return WDI_STATUS_E_FAILURE;
}
-
/*----------------------------------------------------------------------
Avoid Enable PNO during any active session or an ongoing session
- ----------------------------------------------------------------------*/
- if ( (pwdiPNOScanReqParams->wdiPNOScanInfo.bEnable &&
- WDI_GetActiveSessionsCount(pWDICtx, NULL, eWLAN_PAL_FALSE)) )
+ Allow only if SAP auth offload feature is enabled
+ ----------------------------------------------------------------------*/
+ if ((pwdiPNOScanReqParams->wdiPNOScanInfo.bEnable &&
+ WDI_GetActiveSessionsCount(pWDICtx, NULL, eWLAN_PAL_FALSE)) &&
+ !WDI_getFwWlanFeatCaps(SAP_OFFLOADS))
{
- WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
"%s:(Active/Ongoing Session) - Fail request", __func__);
- return WDI_STATUS_E_FAILURE;
+ return WDI_STATUS_E_FAILURE;
}
/*-------------------------------------------------------------------------
@@ -27187,6 +27521,8 @@ WDI_PackRoamScanOffloadParams
pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ValidChannelList,
pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ValidChannelCount);
pRoamCandidateListParams->ValidChannelCount = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ValidChannelCount;
+ pRoamCandidateListParams->WeakZoneRssiThresholdForRoam =
+ pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.WeakZoneRssiThresholdForRoam;
WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
"Values are ssid = %s, RoamOffloadScan=%d,Command=%d,"
@@ -27194,7 +27530,7 @@ WDI_PackRoamScanOffloadParams
"NeighborRoamScanRefreshPeriod=%d,NeighborScanChannelMinTime=%d,"
"NeighborScanChannelMaxTime = %d,EmptyRefreshScanPeriod=%d,"
"mdiePresent=%d,MDID=%d, auth=%d, uce=%d, mce=%d, nProbes=%d,"
- "HomeAwayTime=%d",
+ "HomeAwayTime=%d RssiThesholdForRoam=%d",
pRoamCandidateListParams->ConnectedNetwork.ssId.ssId,
pRoamCandidateListParams->RoamScanOffloadEnabled,
pRoamCandidateListParams->Command,
@@ -27210,7 +27546,8 @@ WDI_PackRoamScanOffloadParams
pRoamCandidateListParams->ConnectedNetwork.encryption,
pRoamCandidateListParams->ConnectedNetwork.mcencryption,
pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.nProbes,
- pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.HomeAwayTime);
+ pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.HomeAwayTime,
+ pRoamCandidateListParams->WeakZoneRssiThresholdForRoam);
pRoamCandidateListParams->us24GProbeSize =
(pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.us24GProbeSize<
WLAN_HAL_ROAM_SCAN_MAX_PROBE_SIZE)?
@@ -27550,6 +27887,54 @@ WDI_ProcessPERRoamScanTriggerRsp
}/* WDI_ProcessPERRoamScanTriggerRsp */
#endif
+#ifdef WLAN_FEATURE_APFIND
+#define FIND_AP_WAKELOCK_TIMEOUT 1000
+/**
+ @brief Process QRF Preferred Network Found Indication function
+
+ @param pWDICtx: pointer to the WLAN DAL context
+ pEventData: pointer to the event information structure
+
+ @see
+ @return Result of the function call
+*/
+WDI_Status
+WDI_ProcessQRFPrefNetworkFoundInd
+(
+ WDI_ControlBlockType* pWDICtx,
+ WDI_EventInfoType* pEventData
+)
+{
+ WDI_LowLevelIndType wdiInd;
+
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+ "%s:%d Enter", __func__, __LINE__);
+
+ /*-------------------------------------------------------------------------
+ Sanity check
+ -------------------------------------------------------------------------*/
+ if (NULL == pWDICtx)
+ {
+ WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+ "%s: Invalid parameters", __func__);
+ WDI_ASSERT( 0 );
+ return WDI_STATUS_E_FAILURE;
+ }
+ vos_wake_lock_timeout_release(&pWDICtx->find_ap_lock,
+ FIND_AP_WAKELOCK_TIMEOUT,
+ WIFI_POWER_EVENT_WAKELOCK_FIND_AP_INDICATION);
+ /*Fill in the indication parameters*/
+ wdiInd.wdiIndicationType = WDI_AP_FOUND_IND;
+ if ( pWDICtx->wdiLowLevelIndCB )
+ {
+ /*Notify UMAC*/
+ pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData );
+ }
+
+ return WDI_STATUS_SUCCESS;
+}
+#endif
+
/**
@brief Process Update Scan Params function
@@ -27926,6 +28311,8 @@ WDI_ProcessPrefNetworkFoundInd
/*Notify UMAC*/
pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData );
}
+ else
+ vos_mem_free( wdiInd.wdiIndicationData.wdiPrefNetworkFoundInd.pData);
return WDI_STATUS_SUCCESS;
}
@@ -33918,6 +34305,210 @@ WDI_ProcessMonStartReq
WDI_MON_START_RSP);
}
+#ifdef DHCP_SERVER_OFFLOAD
+/**
+ * wdi_dhcp_server_offload_rsp() - wdi api for the dhcp server response
+ * @wdi_ctx: pointer to the wdi context
+ * @event_data: pointer to the event data
+ *
+ * Return: WDI_Status
+ * WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status
+wdi_dhcp_server_offload_rsp
+(
+ WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data
+)
+{
+ wdi_dhcp_srv_offload_rsp_cb wdi_dhcp_srv_offload_rsp_callback;
+
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
+ "%s: Enter ", __func__);
+ /*-------------------------------------------------------------------
+ Sanity check
+ -----------------------------------------------------------------*/
+ if ((NULL == wdi_ctx) || (NULL == event_data) ||
+ (NULL == event_data->pEventData))
+ {
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+ "%s: Invalid parameters", __func__);
+ WDI_ASSERT(0);
+ return WDI_STATUS_E_FAILURE;
+ }
+
+ wdi_dhcp_srv_offload_rsp_callback =
+ (wdi_dhcp_srv_offload_rsp_cb)wdi_ctx->pfncRspCB;
+
+ wdi_dhcp_srv_offload_rsp_callback((void *) event_data->pEventData,
+ wdi_ctx->pRspCBUserData);
+
+ return WDI_STATUS_SUCCESS;
+}
+#endif /* DHCP_SERVER_OFFLOAD */
+
+#ifdef MDNS_OFFLOAD
+/**
+ * wdi_mdns_enable_offload_rsp() - wdi api for the mdns enable response
+ * @wdi_ctx: pointer to the wdi context
+ * @event_data: pointer to the event data
+ *
+ * Return: WDI_Status
+ * WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status
+wdi_mdns_enable_offload_rsp
+(
+ WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data
+)
+{
+ wdi_mdns_enable_rsp_cb wdi_mdns_rsp_callback;
+
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
+ "%s: Enter ", __func__);
+ /*-------------------------------------------------------------------
+ Sanity check
+ -----------------------------------------------------------------*/
+ if ((NULL == wdi_ctx) || (NULL == event_data) ||
+ (NULL == event_data->pEventData))
+ {
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+ "%s: Invalid parameters", __func__);
+ WDI_ASSERT(0);
+ return WDI_STATUS_E_FAILURE;
+ }
+
+ wdi_mdns_rsp_callback =
+ (wdi_mdns_enable_rsp_cb)wdi_ctx->pfncRspCB;
+
+ wdi_mdns_rsp_callback((void *) event_data->pEventData,
+ wdi_ctx->pRspCBUserData);
+
+ return WDI_STATUS_SUCCESS;
+}
+
+/**
+ * wdi_mdns_fqdn_offload_rsp() - wdi api for the mdns fqdn response
+ * @wdi_ctx: pointer to the wdi context
+ * @event_data: pointer to the event data
+ *
+ * Return: WDI_Status
+ * WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status
+wdi_mdns_fqdn_offload_rsp
+(
+ WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data
+)
+{
+ wdi_mdns_enable_rsp_cb wdi_mdns_rsp_callback;
+
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
+ "%s: Enter ", __func__);
+ /*-------------------------------------------------------------------
+ Sanity check
+ -----------------------------------------------------------------*/
+ if ((NULL == wdi_ctx) || (NULL == event_data) ||
+ (NULL == event_data->pEventData))
+ {
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+ "%s: Invalid parameters", __func__);
+ WDI_ASSERT(0);
+ return WDI_STATUS_E_FAILURE;
+ }
+
+ wdi_mdns_rsp_callback =
+ (wdi_mdns_enable_rsp_cb)wdi_ctx->pfncRspCB;
+
+ wdi_mdns_rsp_callback((void *) event_data->pEventData,
+ wdi_ctx->pRspCBUserData);
+
+ return WDI_STATUS_SUCCESS;
+}
+
+/**
+ * wdi_mdns_resp_offload_rsp() - wdi api for the mdns resp response
+ * @wdi_ctx: pointer to the wdi context
+ * @event_data: pointer to the event data
+ *
+ * Return: WDI_Status
+ * WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status
+wdi_mdns_resp_offload_rsp
+(
+ WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data
+)
+{
+ wdi_mdns_resp_rsp_cb wdi_mdns_rsp_callback;
+
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
+ "%s: Enter ", __func__);
+ /*-------------------------------------------------------------------
+ Sanity check
+ -----------------------------------------------------------------*/
+ if ((NULL == wdi_ctx) || (NULL == event_data) ||
+ (NULL == event_data->pEventData))
+ {
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+ "%s: Invalid parameters", __func__);
+ WDI_ASSERT(0);
+ return WDI_STATUS_E_FAILURE;
+ }
+
+ wdi_mdns_rsp_callback =
+ (wdi_mdns_resp_rsp_cb)wdi_ctx->pfncRspCB;
+
+ wdi_mdns_rsp_callback((void *) event_data->pEventData,
+ wdi_ctx->pRspCBUserData);
+
+ return WDI_STATUS_SUCCESS;
+}
+
+/**
+ * wdi_get_mdns_stats_offload_rsp() - wdi api for the mdns stats response
+ * @wdi_ctx: pointer to the wdi context
+ * @event_data: pointer to the event data
+ *
+ * Return: WDI_Status
+ * WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status
+wdi_get_mdns_stats_offload_rsp
+(
+ WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data
+)
+{
+ wdi_get_stats_rsp_cb wdi_mdns_rsp_callback;
+
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+ "%s: Enter ", __func__);
+ /*-------------------------------------------------------------------
+ Sanity check
+ -----------------------------------------------------------------*/
+ if ((NULL == wdi_ctx) || (NULL == event_data) ||
+ (NULL == event_data->pEventData))
+ {
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+ "%s: Invalid parameters", __func__);
+ WDI_ASSERT(0);
+ return WDI_STATUS_E_FAILURE;
+ }
+
+ wdi_mdns_rsp_callback =
+ (wdi_get_stats_rsp_cb)wdi_ctx->pfncRspCB;
+
+ wdi_mdns_rsp_callback((void *) event_data->pEventData,
+ wdi_ctx->pRspCBUserData);
+
+ return WDI_STATUS_SUCCESS;
+}
+#endif /* MDNS_OFFLOAD */
+
WDI_Status
WDI_ProcessMonStartRsp
(
@@ -36412,6 +37003,457 @@ WDI_ProcessFatalEventLogsReq
}
+#ifdef DHCP_SERVER_OFFLOAD
+/**
+ * wdi_dhcp_server_offload_req() - wdi api for dhcp server offload
+ * @wdi_ctx: pointer to wdi context
+ * @event_data: pointer to event data
+ *
+ * Return: WDI_Status
+ * WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status
+wdi_dhcp_server_offload_req
+(
+ WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data
+)
+{
+ wdi_set_dhcp_server_offload_t *wdi_dhcp_server_info;
+ wpt_uint8 *buff = NULL;
+ wpt_uint16 data_offset = 0;
+ wpt_uint16 size = 0;
+ WDI_Status wdi_status;
+ hal_dhcp_srv_offload_req_msg_t dhcp_srv_offload_req;
+ wdi_dhcp_srv_offload_rsp_cb wdi_dhcp_srv_offload_rsp_callback;
+
+ VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
+ "%s: %d Enter",__func__, __LINE__);
+
+ /*------------------------------------------------------------------
+ Sanity check
+ ------------------------------------------------------------------*/
+ if ((NULL == wdi_ctx) || (NULL == event_data) ||
+ (NULL == event_data->pEventData))
+ {
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+ "%s: Invalid parameters", __func__);
+ WDI_ASSERT(0);
+ return WDI_STATUS_E_FAILURE;
+ }
+
+ wdi_dhcp_server_info = (wdi_set_dhcp_server_offload_t *)
+ event_data->pEventData;
+
+ /*-------------------------------------------------------------------
+ Get message buffer
+ -----------------------------------------------------------------*/
+ if (( WDI_STATUS_SUCCESS !=
+ WDI_GetMessageBuffer(wdi_ctx,
+ WDI_DHCP_SERVER_OFFLOAD_REQ,
+ sizeof(dhcp_srv_offload_req.
+ dhcp_srv_offload_req_params),
+ &buff, &data_offset, &size))||
+ (size < (data_offset +
+ sizeof(dhcp_srv_offload_req.dhcp_srv_offload_req_params))))
+ {
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
+ "Unable to get send buffer in GetFrameLog Req");
+ WDI_ASSERT(0);
+ return WDI_STATUS_E_FAILURE;
+ }
+
+ dhcp_srv_offload_req.dhcp_srv_offload_req_params.bss_idx =
+ wdi_dhcp_server_info->bssidx;
+ dhcp_srv_offload_req.dhcp_srv_offload_req_params.enable =
+ wdi_dhcp_server_info->enable;
+ dhcp_srv_offload_req.dhcp_srv_offload_req_params.srv_ipv4 =
+ wdi_dhcp_server_info->srv_ipv4;
+ dhcp_srv_offload_req.dhcp_srv_offload_req_params.start_lsb =
+ wdi_dhcp_server_info->start_lsb;
+ dhcp_srv_offload_req.dhcp_srv_offload_req_params.num_client =
+ wdi_dhcp_server_info->num_client;
+
+ wdi_dhcp_srv_offload_rsp_callback = (wdi_dhcp_srv_offload_rsp_cb)
+ event_data->pCBfnc;
+
+ wpalMemoryCopy(buff+data_offset,
+ &dhcp_srv_offload_req.dhcp_srv_offload_req_params,
+ sizeof(dhcp_srv_offload_req.
+ dhcp_srv_offload_req_params));
+
+ /*-------------------------------------------------------------------
+ Send Suspend Request to HAL
+ -----------------------------------------------------------------*/
+ wdi_status = WDI_SendMsg(wdi_ctx, buff, size,
+ wdi_dhcp_srv_offload_rsp_callback,
+ event_data->pUserData,
+ WDI_DHCP_SERVER_OFFLOAD_RSP);
+ VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
+ "%s: %d Exit",__func__, __LINE__);
+ return wdi_status;
+}
+#endif /* DHCP_SERVER_OFFLOAD */
+
+#ifdef MDNS_OFFLOAD
+/**
+ * wdi_mdns_enable_offload_req() - wdi api for dhcp server offload
+ * @wdi_ctx: pointer to wdi context
+ * @event_data: pointer to event data
+ *
+ * Return: WDI_Status
+ * WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status
+wdi_mdns_enable_offload_req
+(
+ WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data
+ )
+{
+ wdi_mdns_enable_offload_cmd_req *wdi_mdns_enable_info;
+ wpt_uint8 *buff = NULL;
+ wpt_uint16 data_offset = 0;
+ wpt_uint16 size = 0;
+ WDI_Status wdi_status;
+ hal_mdns_enable_offload_req_msg_t mdns_enable_req;
+ wdi_mdns_enable_rsp_cb wdi_mdns_enable_rsp_callback;;
+
+ VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
+ "%s: %d Enter",__func__, __LINE__);
+
+ /*------------------------------------------------------------------
+ Sanity check
+ ------------------------------------------------------------------*/
+ if ((NULL == wdi_ctx) || (NULL == event_data) ||
+ (NULL == event_data->pEventData))
+ {
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+ "%s: Invalid parameters", __func__);
+ WDI_ASSERT(0);
+ return WDI_STATUS_E_FAILURE;
+ }
+
+ wdi_mdns_enable_info = (wdi_mdns_enable_offload_cmd_req *)
+ event_data->pEventData;
+
+ /*-------------------------------------------------------------------
+ Get message buffer
+ -----------------------------------------------------------------*/
+ if (( WDI_STATUS_SUCCESS !=
+ WDI_GetMessageBuffer(wdi_ctx,
+ WDI_MDNS_ENABLE_OFFLOAD_REQ,
+ sizeof(mdns_enable_req.
+ mdns_enable_req_params),
+ &buff, &data_offset, &size))||
+ (size < (data_offset +
+ sizeof(mdns_enable_req.mdns_enable_req_params))))
+ {
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
+ "Unable to get send buffer in GetFrameLog Req");
+ WDI_ASSERT(0);
+ return WDI_STATUS_E_FAILURE;
+ }
+
+ mdns_enable_req.mdns_enable_req_params.bss_idx =
+ wdi_mdns_enable_info->bss_idx;
+ mdns_enable_req.mdns_enable_req_params.enable =
+ wdi_mdns_enable_info->enable;
+
+ wdi_mdns_enable_rsp_callback = (wdi_mdns_enable_rsp_cb)
+ event_data->pCBfnc;
+
+ wpalMemoryCopy(buff+data_offset,
+ &mdns_enable_req.mdns_enable_req_params,
+ sizeof(mdns_enable_req.
+ mdns_enable_req_params));
+
+ /*-------------------------------------------------------------------
+ Send Suspend Request to HAL
+ -----------------------------------------------------------------*/
+ wdi_status = WDI_SendMsg(wdi_ctx, buff, size,
+ wdi_mdns_enable_rsp_callback,
+ event_data->pUserData,
+ WDI_MDNS_ENABLE_OFFLOAD_RSP);
+ VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
+ "%s: %d Exit",__func__, __LINE__);
+ return wdi_status;
+}
+
+/**
+ * wdi_mdns_fqdn_offload_req() - wdi api for mdns fqdn offload
+ * @wdi_ctx: pointer to wdi context
+ * @event_data: pointer to event data
+ *
+ * Return: WDI_Status
+ * WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status
+wdi_mdns_fqdn_offload_req
+(
+ WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data
+ )
+{
+ wdi_mdns_set_fqdn_cmd_req *wdi_mdns_fqdn_info;
+ wpt_uint8 *buff = NULL;
+ wpt_uint16 buf_size, data_offset = 0;
+ wpt_uint16 temp_size, size = 0;
+ WDI_Status wdi_status;
+ hal_mdns_fqdn_offload_req_param_t mdns_fqdn;
+ wdi_mdns_fqdn_rsp_cb wdi_mdns_fqdn_rsp_callback;;
+
+ VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
+ "%s: %d Enter",__func__, __LINE__);
+
+ /*------------------------------------------------------------------
+ Sanity check
+ ------------------------------------------------------------------*/
+ if ((NULL == wdi_ctx) || (NULL == event_data) ||
+ (NULL == event_data->pEventData))
+ {
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+ "%s: Invalid parameters", __func__);
+ WDI_ASSERT(0);
+ return WDI_STATUS_E_FAILURE;
+ }
+
+ wdi_mdns_fqdn_info = (wdi_mdns_set_fqdn_cmd_req *)
+ event_data->pEventData;
+
+ mdns_fqdn.bss_idx = wdi_mdns_fqdn_info->bss_idx;
+ mdns_fqdn.type = wdi_mdns_fqdn_info->type;
+ mdns_fqdn.fqdn_len = wdi_mdns_fqdn_info->fqdn_len;
+
+ buf_size = sizeof(mdns_fqdn) + mdns_fqdn.fqdn_len -
+ sizeof(mdns_fqdn.fqdn_data[1]);
+
+ /*-------------------------------------------------------------------
+ Get message buffer
+ -----------------------------------------------------------------*/
+ if (( WDI_STATUS_SUCCESS !=
+ WDI_GetMessageBuffer(wdi_ctx,
+ WDI_MDNS_FQDN_OFFLOAD_REQ,
+ buf_size,
+ &buff, &data_offset, &size))||
+ (size < (data_offset + buf_size)))
+ {
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
+ "Unable to get send buffer in GetFrameLog Req");
+ WDI_ASSERT(0);
+ return WDI_STATUS_E_FAILURE;
+ }
+
+ wdi_mdns_fqdn_rsp_callback = (wdi_mdns_fqdn_rsp_cb)
+ event_data->pCBfnc;
+
+ temp_size = 0;
+ wpalMemoryCopy(buff+data_offset+temp_size,
+ &mdns_fqdn.bss_idx,
+ sizeof(mdns_fqdn.bss_idx));
+ temp_size += sizeof(mdns_fqdn.bss_idx);
+ wpalMemoryCopy(buff+data_offset+temp_size,
+ &mdns_fqdn.type,
+ sizeof(mdns_fqdn.type));
+ temp_size += sizeof(mdns_fqdn.type);
+ wpalMemoryCopy(buff+data_offset+temp_size,
+ &mdns_fqdn.fqdn_len,
+ sizeof(mdns_fqdn.fqdn_len));
+ temp_size += sizeof(mdns_fqdn.fqdn_len);
+ wpalMemoryCopy(buff+data_offset+temp_size,
+ wdi_mdns_fqdn_info->fqdn_data,
+ wdi_mdns_fqdn_info->fqdn_len);
+
+ /*-------------------------------------------------------------------
+ Send Suspend Request to HAL
+ -----------------------------------------------------------------*/
+ wdi_status = WDI_SendMsg(wdi_ctx, buff, size,
+ wdi_mdns_fqdn_rsp_callback,
+ event_data->pUserData,
+ WDI_MDNS_FQDN_OFFLOAD_RSP);
+ VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
+ "%s: %d Exit",__func__, __LINE__);
+ return wdi_status;
+}
+
+/**
+ * wdi_mdns_resp_offload_req() - wdi api for mdns response offload
+ * @wdi_ctx: pointer to wdi context
+ * @event_data: pointer to event data
+ *
+ * Return: WDI_Status
+ * WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status
+wdi_mdns_resp_offload_req
+(
+ WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data
+ )
+{
+ wdi_mdns_set_resp_req *wdi_mdns_resp_info;
+ wpt_uint8 *buff = NULL;
+ wpt_uint16 buf_size, data_offset = 0;
+ wpt_uint16 temp_size, size = 0;
+ WDI_Status wdi_status;
+ hal_mdns_resp_offload_req_param_t mdns_resp;
+ wdi_mdns_resp_rsp_cb wdi_mdns_resp_rsp_callback;;
+
+ VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
+ "%s: %d Enter",__func__, __LINE__);
+
+ /*------------------------------------------------------------------
+ Sanity check
+ ------------------------------------------------------------------*/
+ if ((NULL == wdi_ctx) || (NULL == event_data) ||
+ (NULL == event_data->pEventData))
+ {
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+ "%s: Invalid parameters", __func__);
+ WDI_ASSERT(0);
+ return WDI_STATUS_E_FAILURE;
+ }
+
+ wdi_mdns_resp_info = (wdi_mdns_set_resp_req *)
+ event_data->pEventData;
+
+ mdns_resp.bss_idx = wdi_mdns_resp_info->bss_idx;
+ mdns_resp.ar_count = wdi_mdns_resp_info->ar_count;
+ mdns_resp.resp_len = wdi_mdns_resp_info->resp_len;
+
+ buf_size = sizeof(mdns_resp) + mdns_resp.resp_len -
+ sizeof(mdns_resp.resp_data[1]);
+
+ /*-------------------------------------------------------------------
+ Get message buffer
+ -----------------------------------------------------------------*/
+ if (( WDI_STATUS_SUCCESS !=
+ WDI_GetMessageBuffer(wdi_ctx,
+ WDI_MDNS_RESP_OFFLOAD_REQ,
+ buf_size,
+ &buff, &data_offset, &size))||
+ (size < (data_offset + buf_size)))
+ {
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
+ "Unable to get send buffer in GetFrameLog Req");
+ WDI_ASSERT(0);
+ return WDI_STATUS_E_FAILURE;
+ }
+
+ wdi_mdns_resp_rsp_callback = (wdi_mdns_resp_rsp_cb)
+ event_data->pCBfnc;
+
+ temp_size = 0;
+ wpalMemoryCopy(buff+data_offset+temp_size,
+ &mdns_resp.bss_idx,
+ sizeof(mdns_resp.bss_idx));
+ temp_size += sizeof(mdns_resp.bss_idx);
+ wpalMemoryCopy(buff+data_offset+temp_size,
+ &mdns_resp.ar_count,
+ sizeof(mdns_resp.ar_count));
+ temp_size += sizeof(mdns_resp.ar_count);
+ wpalMemoryCopy(buff+data_offset+temp_size,
+ &mdns_resp.resp_len,
+ sizeof(mdns_resp.resp_len));
+ temp_size += sizeof(mdns_resp.resp_len);
+ wpalMemoryCopy(buff+data_offset+temp_size,
+ &wdi_mdns_resp_info->resp_data,
+ wdi_mdns_resp_info->resp_len);
+
+ /*-------------------------------------------------------------------
+ Send Suspend Request to HAL
+ -----------------------------------------------------------------*/
+ wdi_status = WDI_SendMsg(wdi_ctx, buff, size,
+ wdi_mdns_resp_rsp_callback,
+ event_data->pUserData,
+ WDI_MDNS_RESP_OFFLOAD_RSP);
+ VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
+ "%s: %d Exit",__func__, __LINE__);
+ return wdi_status;
+}
+
+/**
+ * wdi_get_mdns_stats_offload_req() - wdi api for mdns stats offload
+ * @wdi_ctx: pointer to wdi context
+ * @event_data: pointer to event data
+ *
+ * Return: WDI_Status
+ * WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status
+wdi_get_mdns_stats_offload_req
+(
+ WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data
+ )
+{
+ wdi_mdns_get_stats_req *wdi_mdns_stats_info;
+ wpt_uint8 *buff = NULL;
+ wpt_uint16 data_offset = 0;
+ wpt_uint16 size = 0;
+ WDI_Status wdi_status;
+ hal_mdns_stats_offload_req_msg_t mdns_stats_req;
+ wdi_get_stats_rsp_cb wdi_mdns_stats_rsp_callback;;
+
+ VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
+ "%s: %d Enter",__func__, __LINE__);
+
+ /*------------------------------------------------------------------
+ Sanity check
+ ------------------------------------------------------------------*/
+ if ((NULL == wdi_ctx) || (NULL == event_data) ||
+ (NULL == event_data->pEventData))
+ {
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+ "%s: Invalid parameters", __func__);
+ WDI_ASSERT(0);
+ return WDI_STATUS_E_FAILURE;
+ }
+
+ wdi_mdns_stats_info = (wdi_mdns_get_stats_req *)
+ event_data->pEventData;
+
+ /*-------------------------------------------------------------------
+ Get message buffer
+ -----------------------------------------------------------------*/
+ if (( WDI_STATUS_SUCCESS !=
+ WDI_GetMessageBuffer(wdi_ctx,
+ WDI_MDNS_STATS_OFFLOAD_REQ,
+ sizeof(mdns_stats_req.
+ mdns_stats_req_params),
+ &buff, &data_offset, &size))||
+ (size < (data_offset +
+ sizeof(mdns_stats_req.mdns_stats_req_params))))
+ {
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
+ "Unable to get send buffer in GetFrameLog Req");
+ WDI_ASSERT(0);
+ return WDI_STATUS_E_FAILURE;
+ }
+
+ mdns_stats_req.mdns_stats_req_params.bss_idx =
+ wdi_mdns_stats_info->bss_idx;
+
+ wdi_mdns_stats_rsp_callback = (wdi_get_stats_rsp_cb)
+ event_data->pCBfnc;
+
+ wpalMemoryCopy(buff+data_offset,
+ &mdns_stats_req.mdns_stats_req_params,
+ sizeof(mdns_stats_req.
+ mdns_stats_req_params));
+
+ /*-------------------------------------------------------------------
+ Send Suspend Request to HAL
+ -----------------------------------------------------------------*/
+ wdi_status = WDI_SendMsg(wdi_ctx, buff, size,
+ wdi_mdns_stats_rsp_callback,
+ event_data->pUserData,
+ WDI_MDNS_STATS_OFFLOAD_RSP);
+ VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
+ "%s: %d Exit",__func__, __LINE__);
+ return wdi_status;
+}
+#endif /* MDNS_OFFLOAD */
/**
@brief Process FWLoggingInit Request
@@ -37816,6 +38858,92 @@ WDI_SetBcnMissPenaltyCount
#endif
+#ifdef WLAN_FEATURE_APFIND
+WDI_Status WDI_ProcessApFindInd(WDI_ControlBlockType *pWDICtx,
+ WDI_EventInfoType *pEventData)
+{
+ wpt_uint8* pSendBuffer = NULL;
+ wpt_uint16 usDataOffset = 0;
+ wpt_uint16 usSendSize = 0;
+ struct WDI_APFind_cmd *pwdiapFindRequestInd;
+ tQRFPrefNetwListParams *phalAPFindRequestParam;
+ WDI_Status wdiStatus = WDI_STATUS_SUCCESS;
+ wpt_uint16 buffer_len = 0;
+
+ /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+ "%s", __func__);
+
+ /*-------------------------------------------------------------------------
+ Sanity check
+ ------------------------------------------------------------------------*/
+ if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ))
+ {
+ WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
+ "%s: Invalid parameters", __func__);
+ WDI_ASSERT(0);
+ return WDI_STATUS_E_FAILURE;
+ }
+ pwdiapFindRequestInd = (struct WDI_APFind_cmd *)pEventData->pEventData;
+ if (pwdiapFindRequestInd->data_len)
+ buffer_len = sizeof(tQRFPrefNetwListParams);
+ /*-----------------------------------------------------------------------
+ Get message buffer
+ -----------------------------------------------------------------------*/
+ if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(pWDICtx,
+ WDI_SET_AP_FIND_IND,
+ buffer_len,
+ &pSendBuffer, &usDataOffset, &usSendSize))||
+ ( usSendSize < (usDataOffset + sizeof(tQRFPrefNetwListParams) )))
+ {
+ WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
+ "Unable to get send buffer in QRF command %p ",
+ pEventData);
+ WDI_ASSERT(0);
+ return WDI_STATUS_E_FAILURE;
+ }
+ phalAPFindRequestParam =
+ (tQRFPrefNetwListParams *)(pSendBuffer + usDataOffset);
+
+ wpalMemoryCopy(phalAPFindRequestParam,
+ &pwdiapFindRequestInd->data[0],
+ pwdiapFindRequestInd->data_len);
+
+ pWDICtx->pReqStatusUserData = NULL;
+ pWDICtx->pfncRspCB = NULL;
+ /*-------------------------------------------------------------------------
+ Send WDI_SET_AP_FIND_IND Indication to HAL
+ -------------------------------------------------------------------------*/
+
+ wdiStatus = WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize);
+
+ return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus:WDI_STATUS_SUCCESS_SYNC;
+
+}
+
+WDI_Status WDI_process_ap_find_cmd(struct WDI_APFind_cmd *params)
+{
+ WDI_EventInfoType wdiEventData;
+
+ if (eWLAN_PAL_FALSE == gWDIInitialized)
+ {
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+ "WDI API call before module is initialized - Fail req");
+ return WDI_STATUS_E_NOT_ALLOWED;
+ }
+
+ wdiEventData.wdiRequest = WDI_SET_AP_FIND_IND;
+ wdiEventData.pEventData = params;
+ wdiEventData.uEventDataSize = sizeof(*params);
+ wdiEventData.pCBfnc = NULL;
+ wdiEventData.pUserData = NULL;
+
+ return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
+
+}
+#endif
+
/**
* WDI_ProcessSetAllowedActionFramesInd() - Process Allowed action frames
* Indication message and post it to HAL
@@ -38111,3 +39239,372 @@ WDI_GetARPStatsReq
return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}/*WDI_GetARPStatsReq*/
+
+
+#ifdef SAP_AUTH_OFFLOAD
+/**
+ * WDI_ProcessSapAuthOffloadInd() - Process SAP AUTH ofload
+ * Indication message and post it to HAL
+ *
+ * @pWDICtx: pointer to the WLAN DAL context
+ * @pEventData: pointer to the event information structure
+ *
+ * Return: WDI_Status enumeration
+ */
+WDI_Status
+WDI_ProcessSapAuthOffloadInd
+(
+ WDI_ControlBlockType* pWDICtx,
+ WDI_EventInfoType* pEventData
+ )
+{
+ wpt_uint8* pSendBuffer = NULL;
+ wpt_uint16 usDataOffset = 0;
+ wpt_uint16 usSendSize = 0;
+ tSapOffloadEnableMsg *sapOffloadEnableIndParam;
+ struct WDI_sap_ofl_enable_params *pwdiSapOflEnableParams;
+ WDI_Status wdiStatus = WDI_STATUS_SUCCESS;
+ int buffer_len = 0;
+
+ /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
+ "%s", __func__);
+
+ /*-------------------------------------------------------------------------
+ Sanity check
+ -------------------------------------------------------------------------*/
+ if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ))
+ {
+ WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
+ "%s: Invalid parameters", __func__);
+ WDI_ASSERT(0);
+ return WDI_STATUS_E_FAILURE;
+ }
+ /*-----------------------------------------------------------------------
+ Get message buffer
+ -----------------------------------------------------------------------*/
+ pwdiSapOflEnableParams =
+ (struct WDI_sap_ofl_enable_params*)pEventData->pEventData;
+
+ if (pwdiSapOflEnableParams->psk_len)
+ buffer_len = pwdiSapOflEnableParams->psk_len +
+ sizeof(tSapOffloadEnableMsg) - sizeof(tANI_U8);
+ else
+ buffer_len = sizeof(tSapOffloadEnableMsg);
+
+ if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
+ WDI_PROCESS_SAP_AUTH_OFFLOAD_IND,
+ buffer_len,
+ &pSendBuffer, &usDataOffset, &usSendSize))||
+ ( usSendSize < (usDataOffset + sizeof(tSapOffloadEnableMsg) )))
+ {
+ WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
+ "Unable to get send buffer in SAP Auth offload Ind %p ",
+ pEventData);
+ WDI_ASSERT(0);
+ return WDI_STATUS_E_FAILURE;
+ }
+ pwdiSapOflEnableParams =
+ (struct WDI_sap_ofl_enable_params*)pEventData->pEventData;
+ sapOffloadEnableIndParam =
+ (tSapOffloadEnableMsg*)(pSendBuffer + usDataOffset);
+ wpalMemoryCopy(&sapOffloadEnableIndParam->selfMacAddr,
+ &pwdiSapOflEnableParams->macAddr, sizeof(wpt_macAddr));
+
+ sapOffloadEnableIndParam->enable = pwdiSapOflEnableParams->enable;
+ sapOffloadEnableIndParam->rsn_authmode =
+ pwdiSapOflEnableParams->rsn_authmode;
+ sapOffloadEnableIndParam->rsn_ucastcipherset =
+ pwdiSapOflEnableParams->rsn_ucastcipherset;
+ sapOffloadEnableIndParam->rsn_mcastcipherset =
+ pwdiSapOflEnableParams->rsn_mcastcipherset;
+ sapOffloadEnableIndParam->psk_len = pwdiSapOflEnableParams->psk_len;
+ wpalMemoryCopy(&sapOffloadEnableIndParam->psk, &pwdiSapOflEnableParams->key,
+ pwdiSapOflEnableParams->psk_len);
+ pWDICtx->pReqStatusUserData = NULL;
+ pWDICtx->pfncRspCB = NULL;
+ /*-------------------------------------------------------------------------
+ Send SAP_AUTH_OFFLOAD_IND Indication to HAL
+ -------------------------------------------------------------------------*/
+ wdiStatus = WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize);
+ return (wdiStatus != WDI_STATUS_SUCCESS) ?
+ wdiStatus:WDI_STATUS_SUCCESS_SYNC;
+
+}
+
+/**
+ * WDI_process_sap_auth_offload() - Process SAP AUTH offload
+ * Indication message and post it to HAL
+ *
+ * @pWDICtx: pointer to the WLAN DAL context
+ * @pEventData: pointer to the event information structure
+ *
+ * Return: WDI_Status enumeration
+ */
+WDI_Status WDI_process_sap_auth_offload(
+ struct WDI_sap_ofl_enable_params *params)
+{
+ WDI_EventInfoType wdiEventData;
+
+ if (eWLAN_PAL_FALSE == gWDIInitialized)
+ {
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+ "WDI API call before module is initialized - Fail req");
+ return WDI_STATUS_E_NOT_ALLOWED;
+ }
+
+ wdiEventData.wdiRequest = WDI_PROCESS_SAP_AUTH_OFFLOAD_IND;
+ wdiEventData.pEventData = params;
+ wdiEventData.uEventDataSize = sizeof(*params);
+ wdiEventData.pCBfnc = NULL;
+ wdiEventData.pUserData = NULL;
+
+ return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
+}
+
+/**
+ * wdi_process_cap_tsf_req() - Send Capture tsf request to FW.
+ *
+ * @pWDICtx: pointer to the WLAN DAL context
+ * @pEventData: pointer to the event information structure
+ *
+ * Return: WDI_Status enumeration
+ */
+WDI_Status wdi_process_cap_tsf_req(wdi_cap_tsf_params_t *wdi_cap_tsf_req,
+ wdi_tsf_rsp_cb wdi_cap_tsf_rsp_callback,
+ void *user_data)
+{
+ WDI_EventInfoType wdiEventData;
+
+ if (eWLAN_PAL_FALSE == gWDIInitialized)
+ {
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+ "WDI API call before module is initialized - Fail req");
+ return WDI_STATUS_E_NOT_ALLOWED;
+ }
+
+ wdiEventData.wdiRequest = WDI_CAP_TSF_REQ;
+ wdiEventData.pEventData = wdi_cap_tsf_req;
+ wdiEventData.uEventDataSize = sizeof(*wdi_cap_tsf_req);
+ wdiEventData.pCBfnc = wdi_cap_tsf_rsp_callback;
+ wdiEventData.pUserData = user_data;
+
+ return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
+}
+/**
+ * wdi_process_get_tsf_req() - Send Get tsf request to FW.
+ *
+ * @pWDICtx: pointer to the WLAN DAL context
+ * @pEventData: pointer to the event information structure
+ *
+ * Return: WDI_Status enumeration
+ */
+WDI_Status wdi_process_get_tsf_req(wdi_cap_tsf_params_t *wdi_get_tsf_req,
+ wdi_tsf_rsp_cb wdi_tsf_rsp_callback,
+ void *user_data)
+{
+ WDI_EventInfoType wdiEventData;
+
+ if (eWLAN_PAL_FALSE == gWDIInitialized)
+ {
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+ "WDI API call before module is initialized - Fail req");
+ return WDI_STATUS_E_NOT_ALLOWED;
+ }
+
+ wdiEventData.wdiRequest = WDI_GET_TSF_REQ;
+ wdiEventData.pEventData = wdi_get_tsf_req;
+ wdiEventData.uEventDataSize = sizeof(*wdi_get_tsf_req);
+ wdiEventData.pCBfnc = wdi_tsf_rsp_callback;
+ wdiEventData.pUserData = user_data;
+
+ return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
+}
+
+/**
+ * wdi_cap_tsf_req() - wdi api for capture tsf request
+ * @wdi_ctx: pointer to wdi context
+ * @event_data: pointer to event data
+ *
+ * Return: WDI_Status
+ * WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status wdi_cap_tsf_req (WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data)
+{
+
+ wdi_cap_tsf_params_t *wdi_cap_tsf_req_info;
+ wpt_uint8 *buff = NULL;
+ wpt_uint16 data_offset = 0;
+ wpt_uint16 size = 0;
+ WDI_Status wdi_status;
+ tHalCapTSFgetReqInd hal_cap_tsf_req;
+ wdi_tsf_rsp_cb wdi_tsf_rsp_callback;
+
+ VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
+ "%s: Enter",__func__ );
+ /* Sanity check */
+ if ((NULL == wdi_ctx) || (NULL == event_data) ||
+ (NULL == event_data->pEventData)) {
+
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+ "%s: Invalid parameters", __func__);
+ WDI_ASSERT(0);
+ return WDI_STATUS_E_FAILURE;
+ }
+
+ wdi_cap_tsf_req_info = (wdi_cap_tsf_params_t *)
+ event_data->pEventData;
+
+ /* Get message buffer */
+ if (( WDI_STATUS_SUCCESS !=
+ WDI_GetMessageBuffer(wdi_ctx,
+ WDI_CAP_TSF_REQ,
+ sizeof(hal_cap_tsf_req.
+ capTSFget),
+ &buff, &data_offset, &size))||
+ (size < (data_offset +
+ sizeof(hal_cap_tsf_req.capTSFget))))
+ {
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
+ "Unable to get send buffer in GetTsfFrame Req");
+ WDI_ASSERT(0);
+ return WDI_STATUS_E_FAILURE;
+ }
+ hal_cap_tsf_req.capTSFget.uBssIdx = wdi_cap_tsf_req_info->bss_idx;
+ hal_cap_tsf_req.capTSFget.capTSFget = wdi_cap_tsf_req_info->capTSFget;
+
+ wdi_tsf_rsp_callback = (wdi_tsf_rsp_cb)event_data->pCBfnc;
+
+ wpalMemoryCopy(buff+data_offset,
+ &hal_cap_tsf_req.capTSFget,
+ sizeof(hal_cap_tsf_req.capTSFget));
+
+ wdi_status = WDI_SendMsg(wdi_ctx, buff, size,
+ wdi_tsf_rsp_callback,
+ event_data->pUserData,
+ WDI_CAPTURE_GET_TSF_TSTAMP_RSP);
+
+ VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
+ "%s: Exit",__func__);
+
+ return wdi_status;
+}
+
+/**
+ * wdi_get_tsf_req() - wdi api for get tsf request
+ * @wdi_ctx: pointer to wdi context
+ * @event_data: pointer to event data
+ *
+ * Return: WDI_Status
+ * WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status wdi_get_tsf_req (WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data)
+{
+
+ wdi_cap_tsf_params_t *wdi_cap_tsf_req_info;
+ wpt_uint8 *buff = NULL;
+ wpt_uint16 data_offset = 0;
+ wpt_uint16 size = 0;
+ WDI_Status wdi_status;
+ tHalCapTSFgetReqInd hal_cap_tsf_req;
+ wdi_tsf_rsp_cb wdi_tsf_rsp_callback;
+
+ VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
+ "%s: Enter",__func__ );
+ /* Sanity check */
+ if ((NULL == wdi_ctx) || (NULL == event_data) ||
+ (NULL == event_data->pEventData)) {
+
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+ "%s: Invalid parameters", __func__);
+ WDI_ASSERT(0);
+ return WDI_STATUS_E_FAILURE;
+ }
+
+ wdi_cap_tsf_req_info = (wdi_cap_tsf_params_t *)
+ event_data->pEventData;
+
+ /* Get message buffer */
+ if (( WDI_STATUS_SUCCESS !=
+ WDI_GetMessageBuffer(wdi_ctx,
+ WDI_CAP_TSF_REQ,
+ sizeof(hal_cap_tsf_req.
+ capTSFget),
+ &buff, &data_offset, &size))||
+ (size < (data_offset +
+ sizeof(hal_cap_tsf_req.capTSFget))))
+ {
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
+ "Unable to get send buffer in GetTsfFrame Req");
+ WDI_ASSERT(0);
+ return WDI_STATUS_E_FAILURE;
+ }
+ hal_cap_tsf_req.capTSFget.uBssIdx = wdi_cap_tsf_req_info->bss_idx;
+ hal_cap_tsf_req.capTSFget.capTSFget = wdi_cap_tsf_req_info->capTSFget;
+
+ wdi_tsf_rsp_callback = (wdi_tsf_rsp_cb)event_data->pCBfnc;
+
+ wpalMemoryCopy(buff+data_offset,
+ &hal_cap_tsf_req.capTSFget,
+ sizeof(hal_cap_tsf_req.capTSFget));
+
+ wdi_status = WDI_SendMsg(wdi_ctx, buff, size,
+ wdi_tsf_rsp_callback,
+ event_data->pUserData,
+ WDI_CAPTURE_GET_TSF_TSTAMP_RSP);
+
+ VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
+ "%s: Exit",__func__);
+
+ return wdi_status;
+}
+
+/**
+ * wdi_get_tsf_rsp() - wdi api for the get tsf response
+ * @wdi_ctx: pointer to the wdi context
+ * @event_data: pointer to the event data
+ *
+ * Return: WDI_Status
+ * WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status
+wdi_get_tsf_rsp
+(
+ WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data
+)
+{
+ wdi_tsf_rsp_cb wdi_tsf_rsp_callback;
+
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
+ "%s: Enter ", __func__);
+ /*-------------------------------------------------------------------
+ Sanity check
+ -----------------------------------------------------------------*/
+ if ((NULL == wdi_ctx) || (NULL == event_data) ||
+ (NULL == event_data->pEventData))
+ {
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+ "%s: Invalid parameters", __func__);
+ WDI_ASSERT(0);
+ return WDI_STATUS_E_FAILURE;
+ }
+
+ wdi_tsf_rsp_callback =
+ (wdi_tsf_rsp_cb)wdi_ctx->pfncRspCB;
+
+ if (wdi_tsf_rsp_callback)
+ wdi_tsf_rsp_callback((void *) event_data->pEventData,
+ wdi_ctx->pRspCBUserData);
+ else {
+ VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
+ "wdi_tsf_rsp_callback is NULL!");
+ return WDI_STATUS_E_FAILURE;
+ }
+
+ return WDI_STATUS_SUCCESS;
+}
+#endif
diff --git a/drivers/staging/prima/CORE/WDI/CP/src/wlan_qct_wdi_sta.c b/drivers/staging/prima/CORE/WDI/CP/src/wlan_qct_wdi_sta.c
index 9b8aa788bf8..0038a7b3009 100644
--- a/drivers/staging/prima/CORE/WDI/CP/src/wlan_qct_wdi_sta.c
+++ b/drivers/staging/prima/CORE/WDI/CP/src/wlan_qct_wdi_sta.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014, 2016 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -206,7 +206,7 @@ WDI_STATableClose
@brief WDI_STATableAddSta - Function to Add Station
- @param pWDICtx: pointer to the WLAN DAL context
+ @param pWDICtx: pointer to the WLAN DAL context
pwdiParam: station parameters
@see
@@ -215,11 +215,12 @@ WDI_STATableClose
WDI_Status
WDI_STATableAddSta
(
- WDI_ControlBlockType* pWDICtx,
+ void* ctx,
WDI_AddStaParams* pwdiParam
)
{
wpt_uint8 ucSTAIdx = 0;
+ WDI_ControlBlockType* pWDICtx = ctx;
WDI_StaStruct* pSTATable = (WDI_StaStruct*) pWDICtx->staTable;
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
@@ -302,7 +303,7 @@ WDI_STATableAddSta
@brief WDI_STATableDelSta - Function to Delete a Station
- @param pWDICtx: pointer to the WLAN DAL context
+ @param void: pointer to the WLAN DAL context
ucSTAIdx: station to be deleted
@see
@@ -311,10 +312,11 @@ WDI_STATableAddSta
WDI_Status
WDI_STATableDelSta
(
- WDI_ControlBlockType* pWDICtx,
+ void* ctx,
wpt_uint8 ucSTAIdx
)
{
+ WDI_ControlBlockType* pWDICtx = ctx;
WDI_StaStruct* pSTATable = (WDI_StaStruct*) pWDICtx->staTable;
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
@@ -341,7 +343,7 @@ WDI_STATableDelSta
@brief WDI_STATableBSSDelSta - Function to Delete Stations in this BSS
- @param pWDICtx: pointer to the WLAN DAL context
+ @param pWDICtx: pointer to the WLAN DAL context
ucBSSIdx: BSS index
@see
@@ -584,12 +586,13 @@ WDI_CompareMacAddr
WDI_Status
WDI_STATableFindStaidByAddr
(
- WDI_ControlBlockType* pWDICtx,
+ void * context,
wpt_macAddr staAddr,
wpt_uint8* pucStaId
)
{
WDI_Status wdiStatus = WDI_STATUS_E_FAILURE;
+ WDI_ControlBlockType* pWDICtx = context;
wpt_uint8 i;
WDI_StaStruct* pSTATable = (WDI_StaStruct*) pWDICtx->staTable;
diff --git a/drivers/staging/prima/CORE/WDI/DP/inc/wlan_qct_wdi_ds.h b/drivers/staging/prima/CORE/WDI/DP/inc/wlan_qct_wdi_ds.h
index 2acb5cec4cd..4f88b99f6c0 100644
--- a/drivers/staging/prima/CORE/WDI/DP/inc/wlan_qct_wdi_ds.h
+++ b/drivers/staging/prima/CORE/WDI/DP/inc/wlan_qct_wdi_ds.h
@@ -175,6 +175,7 @@ typedef struct
wpt_uint32 extscanBuffer;
#endif
wpt_uint32 loggingData;
+ wpt_uint32 indType;
} WDI_DS_RxMetaInfoType;
typedef struct sPktMetaInfo
@@ -199,6 +200,48 @@ typedef struct
wpt_uint16 reasonCode;
} WDI_DS_LoggingSessionType;
+
+/*----------------------------------------------------------------------------
+ * WDI_AddStaParams
+ * -------------------------------------------------------------------------*/
+typedef struct
+{
+ wpt_uint8 ucSTAIdx;
+ wpt_uint8 ucWmmEnabled;
+ wpt_uint8 ucHTCapable;
+
+ /* MAC Address of STA */
+ wpt_macAddr staMacAddr;
+
+ /*MAC Address of the BSS*/
+ wpt_macAddr macBSSID;
+
+ /* Field to indicate if this is sta entry for itself STA adding entry for itself
+ * or remote (AP adding STA after successful association.
+ * This may or may not be required in production driver.
+ * 0 - Self, 1 other/remote, 2 - bssid
+ */
+ wpt_uint8 ucStaType;
+
+
+ /*DPU Information*/
+ wpt_uint8 dpuIndex; // DPU table index
+ wpt_uint8 dpuSig; // DPU signature
+ wpt_uint8 bcastDpuIndex;
+ wpt_uint8 bcastDpuSignature;
+ wpt_uint8 bcastMgmtDpuIndex;
+ wpt_uint8 bcastMgmtDpuSignature;
+
+
+ /*RMF enabled/disabled*/
+ wpt_uint8 ucRmfEnabled;
+
+ /* Index into the BSS Session table */
+ wpt_uint8 ucBSSIdx;
+
+}WDI_AddStaParams;
+
+
WPT_STATIC WPT_INLINE WDI_DS_RxMetaInfoType* WDI_DS_ExtractRxMetaData (wpt_packet *pFrame)
{
WDI_DS_RxMetaInfoType * pRxMetadata =
@@ -317,6 +360,59 @@ wpt_uint32 WDI_DS_GetReservedResCountPerSTA(void *pContext,
*
*/
WDI_Status WDI_DS_AddSTAMemPool(void *pContext, wpt_uint8 staIndex);
+/**
+ @brief WDI_STATableFindStaidByAddr - Given a station mac address, search
+ for the corresponding station index from the Station Table.
+
+ @param pWDICtx: Context pointer
+staAddr: station address
+pucStaId: output station id
+
+@see
+@return Result of the function call
+*/
+WDI_Status
+WDI_STATableFindStaidByAddr
+(
+ void* pWDICtx,
+ wpt_macAddr staAddr,
+ wpt_uint8* pucStaId
+ );
+
+/**
+ * @brief WDI_STATableAddSta - Function to Add Station
+ *
+ *
+ * @param pWDICtx: pointer to the WLAN DAL context
+ * pwdiParam: station parameters
+ *
+ * @see
+ * @return Result of the function call
+ * */
+WDI_Status
+WDI_STATableAddSta
+(
+ void* pWDICtx,
+ WDI_AddStaParams* pwdiParam
+ );
+
+
+/**
+ * @brief WDI_STATableDelSta - Function to Delete a Station
+ *
+ *
+ * @param pWDICtx: pointer to the WLAN DAL context
+ * ucSTAIdx: station to be deleted
+ *
+ * @see
+ * @return Result of the function call
+ */
+WDI_Status
+WDI_STATableDelSta
+(
+ void* pWDICtx,
+ wpt_uint8 ucSTAIdx
+ );
/* DAL Remove STA from memPool
* Parameters:
diff --git a/drivers/staging/prima/CORE/WDI/TRP/DTS/src/wlan_qct_wdi_dts.c b/drivers/staging/prima/CORE/WDI/TRP/DTS/src/wlan_qct_wdi_dts.c
index a43656a1b41..15a44bcec9f 100644
--- a/drivers/staging/prima/CORE/WDI/TRP/DTS/src/wlan_qct_wdi_dts.c
+++ b/drivers/staging/prima/CORE/WDI/TRP/DTS/src/wlan_qct_wdi_dts.c
@@ -668,6 +668,7 @@ wpt_status WDTS_RxPacket (void *pContext, wpt_packet *pFrame, WDTS_ChannelType c
wpt_uint8 isFcBd = 0;
WDI_DS_LoggingSessionType *pLoggingSession;
tPerPacketStats rxStats = {0};
+ wpt_uint8 indType = 0;
tpSirMacFrameCtl pMacFrameCtl;
// Do Sanity checks
@@ -724,6 +725,7 @@ wpt_status WDTS_RxPacket (void *pContext, wpt_packet *pFrame, WDTS_ChannelType c
bFSF = WDI_RX_BD_GET_ESF(pBDHeader);
bLSF = WDI_RX_BD_GET_LSF(pBDHeader);
isFcBd = WDI_RX_FC_BD_GET_FC(pBDHeader);
+ indType = WDI_RX_BD_GET_PER_SAPOFFLOAD(pBDHeader);
DTI_TRACE( DTI_TRACE_LEVEL_INFO,
"WLAN TL:BD header processing data: HO %d DO %d Len %d HLen %d"
@@ -733,7 +735,6 @@ wpt_status WDTS_RxPacket (void *pContext, wpt_packet *pFrame, WDTS_ChannelType c
pRxMetadata = WDI_DS_ExtractRxMetaData(pFrame);
- // Special handling for frames which contain logging information
if (WDTS_CHANNEL_RX_LOG == channel)
{
if (VPKT_SIZE_BUFFER_ALIGNED < (usMPDULen+ucMPDUHOffset))
@@ -768,10 +769,20 @@ wpt_status WDTS_RxPacket (void *pContext, wpt_packet *pFrame, WDTS_ChannelType c
wpalPacketSetRxLength(pFrame, usMPDULen+ucMPDUHOffset);
wpalPacketRawTrimHead(pFrame, ucMPDUHOffset);
- // Invoke Rx complete callback
- wpalLogPktSerialize(pFrame);
-
- return eWLAN_PAL_STATUS_SUCCESS;
+ if(indType) {
+ DTI_TRACE(DTI_TRACE_LEVEL_INFO, "indtype is %d size of pacekt is %lu",
+ indType, sizeof(WDI_RxBdType));
+ if (WDI_RXBD_SAP_TX_STATS == indType) {
+ pRxMetadata->fc = 1;
+ pClientData->receiveFrameCB(pClientData->pCallbackContext, pFrame);
+ return eWLAN_PAL_STATUS_SUCCESS;
+ }
+ }
+ else {
+ // Invoke Rx complete callback
+ wpalLogPktSerialize(pFrame);
+ return eWLAN_PAL_STATUS_SUCCESS;
+ }
}
else
{
@@ -780,7 +791,9 @@ wpt_status WDTS_RxPacket (void *pContext, wpt_packet *pFrame, WDTS_ChannelType c
if(!isFcBd)
{
- if(usMPDUDOffset <= ucMPDUHOffset || usMPDULen < ucMPDUHLen) {
+ /* When channel is WDTS_CHANNEL_RX_LOG firmware doesn't send MPDU header*/
+ if ((usMPDUDOffset <= ucMPDUHOffset || usMPDULen < ucMPDUHLen) &&
+ (WDTS_CHANNEL_RX_LOG != channel)) {
DTI_TRACE( DTI_TRACE_LEVEL_ERROR,
"WLAN TL:BD header corrupted - dropping packet");
/* Drop packet ???? */
@@ -866,6 +879,30 @@ wpt_status WDTS_RxPacket (void *pContext, wpt_packet *pFrame, WDTS_ChannelType c
pRxMetadata->roamCandidateInd = WDI_RX_BD_GET_ROAMCANDIDATEIND(pBDHeader);
pRxMetadata->perRoamCndInd = WDI_RX_BD_GET_PER_ROAMCANDIDATEIND(pBDHeader);
#endif
+#ifdef SAP_AUTH_OFFLOAD
+ /* Currently firmware use WDTS_CHANNEL_RX_LOG channel for two purpose.
+ * 1) For firmare logging information: driver will do special handling
+ * for those message.
+ * 2) When SAP offload is enabled: In this case, indication type is stored
+ * in pRxMetadata which will be used by LIM later.
+ */
+ if (WDTS_CHANNEL_RX_LOG == channel)
+ {
+ pRxMetadata->indType =
+ (wpt_uint32)WDI_RX_BD_GET_PER_SAPOFFLOAD(pBDHeader);
+ if (pRxMetadata->indType == WDI_RXBD_MLME_STA_STATUS)
+ {
+ DTI_TRACE( DTI_TRACE_LEVEL_INFO, "%s: Indtype is %d\n",
+ __func__, pRxMetadata->indType);
+ pRxMetadata->type = WDI_MAC_MGMT_FRAME;
+ }
+ }
+ else
+ {
+ pRxMetadata->indType = 0;
+ }
+#endif
+
#ifdef WLAN_FEATURE_EXTSCAN
pRxMetadata->extscanBuffer = WDI_RX_BD_GET_EXTSCANFULLSCANRESIND(pBDHeader);
#endif
diff --git a/drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_api.c b/drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_api.c
index ee70505da23..a6019cbdbbf 100644
--- a/drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_api.c
+++ b/drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_api.c
@@ -546,13 +546,7 @@ bool wpalIsArpPkt(void *pPacket)
{
vos_pkt_t *pkt = (vos_pkt_t*)pPacket;
- if (vos_is_arp_pkt(pkt->pSkb, true))
- {
- if (vos_check_arp_req_target_ip(pkt->pSkb, true))
- return true;
- }
-
- return false;
+ return vos_is_arp_pkt(pkt->pSkb, true);
}
void wpalUpdateTXArpFWdeliveredStats(void)
diff --git a/drivers/staging/prima/Kbuild b/drivers/staging/prima/Kbuild
index b7c1f72644e..dfa683e6784 100644
--- a/drivers/staging/prima/Kbuild
+++ b/drivers/staging/prima/Kbuild
@@ -23,12 +23,18 @@ ifeq ($(KERNEL_BUILD), 0)
#Flag to enable Legacy Fast Roaming(LFR)
CONFIG_PRIMA_WLAN_LFR := y
+#Flag to enable Legacy Fast Roaming(LFR) Make Before Break
+ CONFIG_PRIMA_WLAN_LFR_MBB := y
+
#JB kernel has PMKSA patches, hence enabling this flag
CONFIG_PRIMA_WLAN_OKC := y
# JB kernel has CPU enablement patches, so enable
CONFIG_PRIMA_WLAN_11AC_HIGH_TP := y
+#Flag to enable mDNS feature
+ CONFIG_MDNS_OFFLOAD_SUPPORT := y
+
#Flag to enable TDLS feature
CONFIG_QCOM_TDLS := y
@@ -47,6 +53,11 @@ ifneq ($(CONFIG_PRONTO_WLAN),)
CONFIG_WLAN_OFFLOAD_PACKETS := y
endif
+#Flag to enable AP Find feature
+CONFIG_WLAN_FEATURE_AP_FIND := y
+
+# Flag to enable feature Software AP Authentication Offload
+SAP_AUTH_OFFLOAD := y
# To enable CONFIG_QCOM_ESE_UPLOAD, dependent config
# CONFIG_QCOM_ESE must be enabled.
@@ -225,6 +236,10 @@ ifeq ($(CONFIG_QCOM_TDLS),y)
MAC_LIM_OBJS += $(MAC_SRC_DIR)/pe/lim/limProcessTdls.o
endif
+ifeq ($(CONFIG_PRIMA_WLAN_LFR_MBB),y)
+MAC_LIM_OBJS += $(MAC_SRC_DIR)/pe/lim/lim_mbb.o
+endif
+
MAC_PMM_OBJS := $(MAC_SRC_DIR)/pe/pmm/pmmAP.o \
$(MAC_SRC_DIR)/pe/pmm/pmmApi.o \
$(MAC_SRC_DIR)/pe/pmm/pmmDebug.o
@@ -286,6 +301,10 @@ ifeq ($(CONFIG_QCOM_TDLS),y)
SME_CSR_OBJS += $(SME_SRC_DIR)/csr/csrTdlsProcess.o
endif
+ifeq ($(CONFIG_PRIMA_WLAN_LFR_MBB),y)
+SME_CSR_OBJS += $(SME_SRC_DIR)/csr/csr_roam_mbb.o
+endif
+
SME_PMC_OBJS := $(SME_SRC_DIR)/pmc/pmcApi.o \
$(SME_SRC_DIR)/pmc/pmc.o \
$(SME_SRC_DIR)/pmc/pmcLogDump.o
@@ -564,7 +583,9 @@ CDEFINES := -DANI_BUS_TYPE_PLATFORM=1 \
-DWLAN_FEATURE_LINK_LAYER_STATS \
-DWLAN_FEATURE_EXTSCAN \
-DFEATURE_EXT_LL_STAT \
- -DWLAN_VOWIFI_DEBUG
+ -DWLAN_VOWIFI_DEBUG \
+ -DDHCP_SERVER_OFFLOAD \
+ -DWLAN_FEATURE_TSF
ifneq ($(CONFIG_PRONTO_WLAN),)
CDEFINES += -DWCN_PRONTO
@@ -617,6 +638,10 @@ ifeq ($(CONFIG_PRIMA_WLAN_LFR),y)
CDEFINES += -DFEATURE_WLAN_LFR
endif
+ifeq ($(CONFIG_PRIMA_WLAN_LFR_MBB),y)
+CDEFINES += -DWLAN_FEATURE_LFR_MBB
+endif
+
ifeq ($(CONFIG_PRIMA_WLAN_OKC),y)
CDEFINES += -DFEATURE_WLAN_OKC
endif
@@ -658,6 +683,15 @@ ifeq ($(CONFIG_ENABLE_LINUX_REG), y)
CDEFINES += -DCONFIG_ENABLE_LINUX_REG
endif
+# Enable feature SAP Authentication Offload
+ifeq ($(SAP_AUTH_OFFLOAD), y)
+CDEFINES += -DSAP_AUTH_OFFLOAD
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_AP_FIND), y)
+CDEFINES += -DWLAN_FEATURE_APFIND
+endif
+
CDEFINES += -DFEATURE_WLAN_CH_AVOID
CDEFINES += -DWLAN_FEATURE_AP_HT40_24G
@@ -679,6 +713,10 @@ ifeq ($(CONFIG_WLAN_OFFLOAD_PACKETS),y)
CDEFINES += -DWLAN_FEATURE_OFFLOAD_PACKETS
endif
+ifeq ($(CONFIG_MDNS_OFFLOAD_SUPPORT), y)
+CDEFINES += -DMDNS_OFFLOAD
+endif
+
KBUILD_CPPFLAGS += $(CDEFINES)
# Module information used by KBuild framework
diff --git a/drivers/staging/prima/Kconfig b/drivers/staging/prima/Kconfig
index e3cf3f3477e..e3fcf736961 100644
--- a/drivers/staging/prima/Kconfig
+++ b/drivers/staging/prima/Kconfig
@@ -54,7 +54,7 @@ config WLAN_OFFLOAD_PACKETS
default n
config QCOM_TDLS
- bool "Enable TDLS feature"
- default n
+ bool "Enable TDLS feature"
+ default n
endif # PRIMA_WLAN || PRONTO_WLAN
diff --git a/drivers/staging/prima/firmware_bin/WCNSS_qcom_cfg.ini b/drivers/staging/prima/firmware_bin/WCNSS_qcom_cfg.ini
index 97b61e9b4f7..dbb09688542 100644
--- a/drivers/staging/prima/firmware_bin/WCNSS_qcom_cfg.ini
+++ b/drivers/staging/prima/firmware_bin/WCNSS_qcom_cfg.ini
@@ -477,6 +477,52 @@ gTcpDelAckThresholdHigh=17000
#Delack set lower limit
gTcpDelAckThresholdLow=12000
+# Enable or Disable DHCP Server offload
+# 1=Enable, 0=Disable (default)
+gDHCPServerOffloadEnable=0
+
+# Set max number of DHCP Clients
+# Its value could not be greater than 2(default)
+#gDHCPMaxNumClients=2
+
+# Set DHCP server IP
+# 4th field could not be greater than 99, that is xxx.xxx.xxx.0 ~ xxx.xxx.xxx.99
+# 1st field could not be within the range of 224 ~ 239 (multicast IP address)
+# 192.168.1.2(default)
+#gDHCPServerIP=192.168.1.2
+
+# Set DHCP pool start Lsb
+# min 100 (default)
+# max 255
+gDHCPStartLsb=100
+
+# mDNS enable
+gMDNSOffloadEnable=1
+# mDNS FQDN query
+gMDNSFqdn="_GoProRemote._tcp.local"
+# mDNS UFQDN query
+gMDNSUniqueFqdn="service._GoProRemote._tcp.local"
+# mDNS response typeA
+gMDNSResponseTypeA="goprobp-D89685121212.local"
+# mDNS response typeAIpv4Addr
+gMDNSResponseTypeAIpv4Addr=0xc0a80102
+# mDNS response typeTXT
+gMDNSResponseTypeTXT="GoProBP-D89685121212._GoProRemote._tcp.local"
+# mDNS response typeTXTContent
+gMDNSResponseTypeTXTContent="Device=HERO 3+-BAWA Model=BAWA Version=HD3.11.02.00 Wifi Version=4.0.36.0 Protocol Version=2"
+# mDNS response typePTR
+gMDNSResponseTypePTR="_GoProRemote._tcp.local"
+# mDNS response typePTRDomainName
+gMDNSResponseTypePTRDomainName="GoProBP-D89685121212._GoProRemote._tcp.local"
+# mDNS response typeSRV
+gMDNSResponseTypeSRV="GoProBP-D89685121212._GoProRemote._tcp.local"
+# mDNS response typeSRVTarget
+gMDNSResponseTypeSRVTarget="goprobp-D89685121212.local"
+# mDNS response typeSRVPriority
+gMDNSResponseTypeSRVPriority=0
+# mDNS response typeSRVWeight
+gMDNSResponseTypeSRVWeight=0
+
END
# Note: Configuration parser would not read anything past the END marker
diff --git a/drivers/staging/prima/riva/inc/wlan_hal_cfg.h b/drivers/staging/prima/riva/inc/wlan_hal_cfg.h
index 31f59ee3dc4..8c4f277c045 100644
--- a/drivers/staging/prima/riva/inc/wlan_hal_cfg.h
+++ b/drivers/staging/prima/riva/inc/wlan_hal_cfg.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2013,2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013,2016,2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -278,12 +278,14 @@
#define QWLAN_HAL_CFG_SAR_BOFFSET_CORRECTION_ENABLE 220
#define QWLAN_HAL_CFG_UNITS_OF_BCN_WAIT_TIME 221
#define QWLAN_HAL_CFG_CONS_BCNMISS_COUNT 222
+#define QWLAN_HAL_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL 223
#define QWLAN_HAL_CFG_DISABLE_SCAN_DURING_SCO 224
+#define QWLAN_HAL_CFG_TRIGGER_NULLFRAME_BEFORE_HB 225
-#define QWLAN_HAL_CFG_MAX_PARAMS 225
+#define QWLAN_HAL_CFG_MAX_PARAMS 226
/* Total number of Integer CFGs. This is used while allocating the memory for TLV */
-#define QWLAN_HAL_CFG_INTEGER_PARAM 225
+#define QWLAN_HAL_CFG_INTEGER_PARAM 226
/*-------------------------------------------------------------------------
Configuration Parameter min, max, defaults
@@ -1106,4 +1108,9 @@
#define QWLAN_HAL_CFG_BAR_WAKEUP_HOST_DISABLE_MAX 1
#define QWLAN_HAL_CFG_BAR_WAKEUP_HOST_DISABLE_DEF 0
+/* QWLAN_HAL_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL */
+#define QWLAN_HAL_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_MIN 0
+#define QWLAN_HAL_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_MAX 1
+#define QWLAN_HAL_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_DEF 0
+
#endif //__WLAN_HAL_CFG_H__
diff --git a/drivers/staging/prima/riva/inc/wlan_hal_msg.h b/drivers/staging/prima/riva/inc/wlan_hal_msg.h
index 482adfc380d..64b090a26ff 100644
--- a/drivers/staging/prima/riva/inc/wlan_hal_msg.h
+++ b/drivers/staging/prima/riva/inc/wlan_hal_msg.h
@@ -123,7 +123,7 @@ typedef tANI_U8 tHalIpv4Addr[4];
/* 80 is actually NUM_RF_CHANNELS_V2, but beyond V2, this number will be ignored by FW */
#define WLAN_HAL_ROAM_SCAN_MAX_CHANNELS 80
#define WLAN_HAL_ROAM_SACN_PMK_SIZE 32
-#define WLAN_HAL_ROAM_SCAN_RESERVED_BYTES 20
+#define WLAN_HAL_ROAM_SCAN_RESERVED_BYTES 19
#define WLAN_HAL_EXT_SCAN_MAX_CHANNELS 16
#define WLAN_HAL_EXT_SCAN_MAX_BUCKETS 16
@@ -605,6 +605,24 @@ typedef enum
WLAN_HAL_PER_ROAM_SCAN_TRIGGER_REQ = 336,
WLAN_HAL_PER_ROAM_SCAN_TRIGGER_RSP = 337,
+ WLAN_HAL_DHCP_SERVER_OFFLOAD_REQ = 339,
+ WLAN_HAL_DHCP_SERVER_OFFLOAD_RSP = 340,
+ WLAN_HAL_SAP_AUTH_OFFLOAD_IND = 341,
+ WLAN_HAL_MDNS_ENABLE_OFFLOAD_REQ = 342,
+ WLAN_HAL_MDNS_ENABLE_OFFLOAD_RSP = 343,
+ WLAN_HAL_MDNS_FQDN_OFFLOAD_REQ = 344,
+ WLAN_HAL_MDNS_FQDN_OFFLOAD_RSP = 345,
+ WLAN_HAL_MDNS_RESP_OFFLOAD_REQ = 346,
+ WLAN_HAL_MDNS_RESP_OFFLOAD_RSP = 347,
+ WLAN_HAL_MDNS_STATS_OFFLOAD_REQ = 348,
+ WLAN_HAL_MDNS_STATS_OFFLOAD_RSP = 349,
+
+ /* QRF Support */
+ WLAN_HAL_QRF_AP_FIND_COMMAND = 350,
+ WLAN_HAL_QRF_PREF_NETW_FOUND_IND = 351,
+ WLAN_HAL_CAPTURE_GET_TSF_TSTAMP = 352,
+ WLAN_HAL_CAPTURE_GET_TSF_TSTAMP_RSP = 353,
+ /* ARP DEBUG stats*/
WLAN_HAL_FW_SET_CLEAR_ARP_STATS_REQ = 354,
WLAN_HAL_FW_SET_CLEAR_ARP_STATS_RSP = 355,
WLAN_HAL_FW_GET_ARP_STATS_REQ = 356,
@@ -824,6 +842,9 @@ typedef enum eSriLinkState {
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
eSIR_LINK_FT_PREASSOC_STATE = 16,
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+ eSIR_LINK_PRE_AUTH_REASSOC_STATE = 17,
+#endif
eSIR_LINK_MAX = WLAN_HAL_MAX_ENUM_SIZE
} tSirLinkState;
@@ -6370,6 +6391,7 @@ typedef PACKED_PRE struct PACKED_POST {
tANI_U8 Prefer5GHz;
tANI_U8 RoamRssiCatGap;
tANI_U8 Select5GHzMargin;
+ tANI_U8 WeakZoneRssiThresholdForRoam;
tANI_U8 ReservedBytes[WLAN_HAL_ROAM_SCAN_RESERVED_BYTES];
tRoamNetworkType ConnectedNetwork;
tMobilityDomainInfo MDID;
@@ -6897,6 +6919,10 @@ typedef enum {
WIFI_CONFIG = 61,
ANTENNA_DIVERSITY_SELECTION = 62,
PER_BASED_ROAMING = 63,
+ SAP_MODE_WOW = 64,
+ SAP_OFFLOADS = 65,
+ SAP_BUFF_ALLOC = 66,
+ MAKE_BEFORE_BREAK = 67,
NUD_DEBUG = 68,
/* 69 reserved for FATAL_EVENT_LOGGING */
/* 70 reserved for WIFI_DUAL_BAND_ENABLE */
@@ -9089,6 +9115,39 @@ typedef PACKED_PRE struct PACKED_POST
tConfigRoamScanRspParams configRoamScanRspParams;
} tSetRoamScanConfigRsp, * tpSetRoamScanConfigRsp;
+/*---------------------------------------------------------------------------
+* WLAN_HAL_CAPTURE_GET_TSF_TSTAMP
+*-------------------------------------------------------------------------*/
+typedef PACKED_PRE struct PACKED_POST
+{
+ uint8 uBssIdx;
+ boolean capTSFget;
+}tHalCapTSFget, *tptHalCapTSFget;
+
+typedef PACKED_PRE struct PACKED_POST
+{
+ tHalMsgHeader header;
+ tHalCapTSFget capTSFget;
+}tHalCapTSFgetReqInd, *tpHalCapTSFgetReqInd;
+
+/*---------------------------------------------------------------------------
+ WLAN_HAL_CAPTURE_GET_TSF_TSTAMP_RSP
+---------------------------------------------------------------------------*/
+
+typedef PACKED_PRE struct PACKED_POST
+{
+ /* Success /Failure / Nil result */
+ tANI_U32 status;
+ tANI_U32 tsf_lo;
+ tANI_U32 tsf_hi;
+} tConfigcapTSFgetRspParams, * tptConfigcapTSFgetRspParams;
+
+typedef PACKED_PRE struct PACKED_POST
+{
+ tHalMsgHeader header;
+ tConfigcapTSFgetRspParams configcapTSFgetRspParams;
+} tcapGetTSFConfigRsp, * tpcapGetTSFConfigRsp;
+
#define PER_ROAM_MAX_AP_CNT 30
#define PER_ROAM_MAX_CANDIDATE_CNT 15
@@ -9128,6 +9187,75 @@ typedef PACKED_PRE struct PACKED_POST
} tFWLoggingDxeDoneIndMsg, * tpFWLoggingDxeDoneIndMsg;
/*---------------------------------------------------------------------------
+ * WLAN_HAL_APFIND_CMDID
+ * ---------------------------------------------------------------------------*/
+
+#define MAX_ARRAY_SIZE 1000
+typedef PACKED_PRE struct PACKED_POST
+{
+ tANI_U16 msg_version:4;
+ tANI_U16 msg_id:12;
+ tANI_U16 msg_len:16;
+ tANI_U16 handle;
+ tANI_U16 transaction_id;
+} tApfindMsgHeader, *tpApfindMsgHeader;
+
+typedef PACKED_PRE struct PACKED_POST
+{
+ tANI_U16 type;
+ tANI_U16 length;
+ tANI_U8* value;
+} tApfindTlv, *tpApfindTlv;
+
+typedef PACKED_PRE struct PACKED_POST
+{
+ tApfindMsgHeader apFindHeader;
+ tANI_U8 ptlv[MAX_ARRAY_SIZE];
+} tQRFPrefNetwListParams, *tpQRFPrefNetwListParams;
+
+typedef enum
+{
+ APFIND_MSG_ID_ERROR_RSP = 0,
+ APFIND_MSG_ID_ENABLE_REQ = 1,
+ APFIND_MSG_ID_SET_SSID = 2,
+ APFIND_MSG_ID_SET_MAC = 3,
+ APFIND_MSG_ID_SET_PARAMS = 4,
+} tApfindMsgId;
+
+typedef PACKED_PRE struct PACKED_POST
+{
+ tHalMsgHeader header;
+ tQRFPrefNetwListParams qRFprefNetwListParams;
+} tQRFSetPrefNetwListReq, *tpQRFSetPrefNetwListReq;
+
+#define QRF_MAX_SUPPORTED_NETWORKS 10
+
+typedef PACKED_PRE struct PACKED_POST {
+ /*Network that was found with the highest RSSI*/
+ tSirMacSSid ssId;
+ /*Indicates the RSSI */
+ tANI_U8 rssi;
+ /* The MPDU frame length of a beacon or probe rsp.
+ * data is the start of the frame
+ */
+ tANI_U16 frameLength;
+} tQrfNetwFoundParam, *tpQrfNetwFoundParam;
+
+typedef PACKED_PRE struct PACKED_POST {
+ uint8 netwCount;
+ tQrfNetwFoundParam qrfNetwParams[QRF_MAX_SUPPORTED_NETWORKS];
+} tQrfPrefNetwFoundParams, * tpQrfPrefNetwFoundParams;
+
+/*
+ * Preferred network found indication
+ */
+typedef PACKED_PRE struct PACKED_POST {
+ tHalMsgHeader header;
+ tQrfPrefNetwFoundParams qrfPrefNetwFoundParams;
+} tQrfPrefNetwFoundInd, *tpQrfPrefNetwFoundInd;
+
+
+/*---------------------------------------------------------------------------
* Logging mail box structure
*-------------------------------------------------------------------------*/
@@ -9327,6 +9455,184 @@ typedef PACKED_PRE struct PACKED_POST
tHalModifyRoamParamsIndParams modifyRoamParamsReqParams;
} tHalModifyRoamParamsInd, *tpHalModifyRoamParamsInd;
+typedef PACKED_PRE struct PACKED_POST
+{
+ tSirMacAddr selfMacAddr;
+ tANI_U32 enable;
+ tSirMacSSid ssId;
+ tANI_U32 rsn_authmode;
+ tANI_U32 rsn_ucastcipherset;
+ tANI_U32 rsn_mcastcipherset;
+ tANI_U32 rsn_mcastmgmtcipherset;
+ tANI_U32 channel;
+ tANI_U32 psk_len;
+ tANI_U8 psk[1];
+} tSapOffloadEnableMsg, *tpSapOffloadEnableMsg;
+
+typedef PACKED_PRE struct PACKED_POST
+{
+ tHalMsgHeader header;
+ tSapOffloadEnableMsg SapOffloadEnableMsg;
+} tHalSapoffloadEnable, *tpHalSapoffloadEnable;
+
+/*---------------------------------------------------------------------------
+ * WLAN_HAL_DHCP_SERVER_OFFLOAD_REQ
+ *--------------------------------------------------------------------------*/
+typedef PACKED_PRE struct PACKED_POST
+{
+ tANI_U8 bss_idx;
+ tANI_U32 enable;
+ tANI_U32 srv_ipv4; /* server IP */
+ tANI_U32 start_lsb; /* starting address assigned to client */
+ tANI_U32 num_client; /* number of clients we support */
+} hal_dhcp_srv_offload_req_param_t, *hal_dhcp_srv_offload_req_params;
+
+typedef PACKED_PRE struct PACKED_POST
+{
+ tHalMsgHeader header;
+ hal_dhcp_srv_offload_req_param_t dhcp_srv_offload_req_params;
+} hal_dhcp_srv_offload_req_msg_t;
+
+/*---------------------------------------------------------------------------
+ * WLAN_HAL_DHCP_SERVER_OFFLOAD_RSP
+ *--------------------------------------------------------------------------*/
+typedef PACKED_PRE struct PACKED_POST
+{
+ tANI_U32 status;
+} hal_dhcp_srv_offload_rsp_param_t, *hal_dhcp_srv_offload_rsp_params;
+
+typedef PACKED_PRE struct PACKED_POST
+{
+ tHalMsgHeader header;
+ hal_dhcp_srv_offload_rsp_param_t dhcp_srv_offload_rsp_params;
+} hal_dhcp_srv_offload_rsp_msg_t, *hal_dhcp_srv_offload_rsp_msg;
+
+/*---------------------------------------------------------------------------
+ * WLAN_HAL_MDNS_ENABLE_OFFLOAD_REQ
+ *--------------------------------------------------------------------------*/
+typedef PACKED_PRE struct PACKED_POST
+{
+ tANI_U8 bss_idx;
+ tANI_U32 enable;
+} hal_mdns_enable_offload_req_param_t, *hal_mdns_enable_offload_req_params;
+
+typedef PACKED_PRE struct PACKED_POST
+{
+ tHalMsgHeader header;
+ hal_mdns_enable_offload_req_param_t mdns_enable_req_params;
+} hal_mdns_enable_offload_req_msg_t;
+
+/*---------------------------------------------------------------------------
+ * WLAN_HAL_MDNS_ENABLE_OFFLOAD_RSP
+ *--------------------------------------------------------------------------*/
+typedef PACKED_PRE struct PACKED_POST
+{
+ tANI_U32 status;
+} hal_mdns_enable_offload_rsp_param_t, *hal_mdns_enable_offload_rsp_params;
+
+typedef PACKED_PRE struct PACKED_POST
+{
+ tHalMsgHeader header;
+ hal_mdns_enable_offload_rsp_param_t mdns_enable_rsp_params;
+} hal_mdns_enable_offload_rsp_msg_t, *hal_mdns_enable_offload_rsp_msg;
+
+/*---------------------------------------------------------------------------
+ * WLAN_HAL_MDNS_FQDN_OFFLOAD_REQ
+ *--------------------------------------------------------------------------*/
+typedef PACKED_PRE struct PACKED_POST
+{
+ tANI_U8 bss_idx;
+ tANI_U32 type;
+ tANI_U32 fqdn_len;
+ tANI_U8 fqdn_data[1];
+} hal_mdns_fqdn_offload_req_param_t, *hal_mdns_fqdn_offload_req_params;
+
+typedef PACKED_PRE struct PACKED_POST
+{
+ tHalMsgHeader header;
+ hal_mdns_fqdn_offload_req_param_t mdns_fqdn_req_params;
+} hal_mdns_fqdn_offload_req_msg_t;
+
+/*---------------------------------------------------------------------------
+ * WLAN_HAL_MDNS_FQDN_OFFLOAD_RSP
+ *--------------------------------------------------------------------------*/
+typedef PACKED_PRE struct PACKED_POST
+{
+ tANI_U32 status;
+} hal_mdns_fqdn_offload_rsp_param_t, *hal_mdns_fqdn_offload_rsp_params;
+
+typedef PACKED_PRE struct PACKED_POST
+{
+ tHalMsgHeader header;
+ hal_mdns_fqdn_offload_rsp_param_t mdns_fqdn_rsp_params;
+} hal_mdns_fqdn_offload_rsp_msg_t, *hal_mdns_fqdn_offload_rsp_msg;
+
+/*---------------------------------------------------------------------------
+ * WLAN_HAL_MDNS_RESP_OFFLOAD_REQ
+ *--------------------------------------------------------------------------*/
+typedef PACKED_PRE struct PACKED_POST
+{
+ tANI_U8 bss_idx;
+ tANI_U32 ar_count;
+ tANI_U32 resp_len;
+ tANI_U8 resp_data[1];
+} hal_mdns_resp_offload_req_param_t, *hal_mdns_resp_offload_req_params;
+
+typedef PACKED_PRE struct PACKED_POST
+{
+ tHalMsgHeader header;
+ hal_mdns_resp_offload_req_param_t mdns_resp_req_params;
+} hal_mdns_resp_offload_req_msg_t;
+
+/*---------------------------------------------------------------------------
+ * WLAN_HAL_MDNS_RESP_OFFLOAD_RSP
+ *--------------------------------------------------------------------------*/
+typedef PACKED_PRE struct PACKED_POST
+{
+ tANI_U32 status;
+} hal_mdns_resp_offload_rsp_param_t, *hal_mdns_resp_offload_rsp_params;
+
+typedef PACKED_PRE struct PACKED_POST
+{
+ tHalMsgHeader header;
+ hal_mdns_resp_offload_rsp_param_t mdns_rsp_params;
+} hal_mdns_resp_offload_rsp_msg_t, *hal_mdns_resp_offload_rsp_msg;
+
+/*---------------------------------------------------------------------------
+ * WLAN_HAL_MDNS_STATS_OFFLOAD_REQ
+ *--------------------------------------------------------------------------*/
+typedef PACKED_PRE struct PACKED_POST
+{
+ tANI_U8 bss_idx;
+} hal_mdns_stats_offload_req_param_t, *hal_mdns_stats_offload_req_params;
+
+typedef PACKED_PRE struct PACKED_POST
+{
+ tHalMsgHeader header;
+ hal_mdns_stats_offload_req_param_t mdns_stats_req_params;
+} hal_mdns_stats_offload_req_msg_t;
+
+/*---------------------------------------------------------------------------
+ * WLAN_HAL_MDNS_STATS_OFFLOAD_RSP
+ *--------------------------------------------------------------------------*/
+typedef PACKED_PRE struct PACKED_POST
+{
+ tANI_U8 bss_idx;
+ tANI_U32 current_ts;
+ tANI_U32 last_query_ts;
+ tANI_U32 last_rsp_ts;
+ tANI_U32 tot_queries;
+ tANI_U32 tot_matches;
+ tANI_U32 tot_rsp;
+ tANI_U32 status;
+} hal_mdns_stats_offload_rsp_param_t, *hal_mdns_stats_offload_rsp_params;
+
+typedef PACKED_PRE struct PACKED_POST
+{
+ tHalMsgHeader header;
+ hal_mdns_stats_offload_rsp_param_t mdns_stats_rsp_params;
+} hal_mdns_stats_offload_rsp_msg_t, *hal_mdns_stats_offload_rsp_msg;
+
/*---------------------------------------------------------------------------
* WLAN_HAL_FW_SET_CLEAR_ARP_STATS_REQ
*--------------------------------------------------------------------------*/
diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c
index 04c775cb3e6..179f7810d39 100644
--- a/drivers/target/target_core_fabric_configfs.c
+++ b/drivers/target/target_core_fabric_configfs.c
@@ -84,6 +84,11 @@ static int target_fabric_mappedlun_link(
"_tpg does not exist\n");
return -EINVAL;
}
+ if (lun->lun_shutdown) {
+ pr_err("Unable to create mappedlun symlink because"
+ " lun->lun_shutdown=true\n");
+ return -EINVAL;
+ }
se_tpg = lun->lun_sep->sep_tpg;
nacl_ci = &lun_acl_ci->ci_parent->ci_group->cg_item;
diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c
index 8572207e3d4..bc3092f032b 100644
--- a/drivers/target/target_core_tpg.c
+++ b/drivers/target/target_core_tpg.c
@@ -839,6 +839,8 @@ static void core_tpg_shutdown_lun(
struct se_portal_group *tpg,
struct se_lun *lun)
{
+ lun->lun_shutdown = true;
+
core_clear_lun_from_tpg(lun, tpg);
transport_clear_lun_from_sessions(lun);
}
@@ -868,6 +870,7 @@ struct se_lun *core_tpg_pre_dellun(
spin_unlock(&tpg->tpg_lun_lock);
return ERR_PTR(-ENODEV);
}
+ lun->lun_shutdown = false;
spin_unlock(&tpg->tpg_lun_lock);
return lun;
diff --git a/drivers/tty/serial/efm32-uart.c b/drivers/tty/serial/efm32-uart.c
index 7d199c8e1a7..c9635f1c710 100644
--- a/drivers/tty/serial/efm32-uart.c
+++ b/drivers/tty/serial/efm32-uart.c
@@ -27,6 +27,7 @@
#define UARTn_FRAME 0x04
#define UARTn_FRAME_DATABITS__MASK 0x000f
#define UARTn_FRAME_DATABITS(n) ((n) - 3)
+#define UARTn_FRAME_PARITY__MASK 0x0300
#define UARTn_FRAME_PARITY_NONE 0x0000
#define UARTn_FRAME_PARITY_EVEN 0x0200
#define UARTn_FRAME_PARITY_ODD 0x0300
@@ -578,12 +579,16 @@ static void efm32_uart_console_get_options(struct efm32_uart_port *efm_port,
16 * (4 + (clkdiv >> 6)));
frame = efm32_uart_read32(efm_port, UARTn_FRAME);
- if (frame & UARTn_FRAME_PARITY_ODD)
+ switch (frame & UARTn_FRAME_PARITY__MASK) {
+ case UARTn_FRAME_PARITY_ODD:
*parity = 'o';
- else if (frame & UARTn_FRAME_PARITY_EVEN)
+ break;
+ case UARTn_FRAME_PARITY_EVEN:
*parity = 'e';
- else
+ break;
+ default:
*parity = 'n';
+ }
*bits = (frame & UARTn_FRAME_DATABITS__MASK) -
UARTn_FRAME_DATABITS(4) + 4;
diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c
index 8b1534c424a..be3dc751dfb 100644
--- a/drivers/tty/serial/ifx6x60.c
+++ b/drivers/tty/serial/ifx6x60.c
@@ -1379,9 +1379,9 @@ static struct spi_driver ifx_spi_driver = {
static void __exit ifx_spi_exit(void)
{
/* unregister */
+ spi_unregister_driver((void *)&ifx_spi_driver);
tty_unregister_driver(tty_drv);
put_tty_driver(tty_drv);
- spi_unregister_driver((void *)&ifx_spi_driver);
unregister_reboot_notifier(&ifx_modem_reboot_notifier_block);
}
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 010ec70d59f..3390a39f5a7 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2601,13 +2601,13 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
* related to the kernel should not use this.
*/
data = vt_get_shift_state();
- ret = __put_user(data, p);
+ ret = put_user(data, p);
break;
case TIOCL_GETMOUSEREPORTING:
console_lock(); /* May be overkill */
data = mouse_reporting();
console_unlock();
- ret = __put_user(data, p);
+ ret = put_user(data, p);
break;
case TIOCL_SETVESABLANK:
console_lock();
@@ -2616,7 +2616,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
break;
case TIOCL_GETKMSGREDIRECT:
data = vt_get_kmsg_redirect();
- ret = __put_user(data, p);
+ ret = put_user(data, p);
break;
case TIOCL_SETKMSGREDIRECT:
if (!capable(CAP_SYS_ADMIN)) {
diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c
index 0ac843abce8..9b3a925110e 100644
--- a/drivers/usb/chipidea/debug.c
+++ b/drivers/usb/chipidea/debug.c
@@ -242,7 +242,8 @@ static int ci_role_show(struct seq_file *s, void *data)
{
struct ci13xxx *ci = s->private;
- seq_printf(s, "%s\n", ci_role(ci)->name);
+ if (ci->role != CI_ROLE_END)
+ seq_printf(s, "%s\n", ci_role(ci)->name);
return 0;
}
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index c8555041373..a1748841d56 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -511,8 +511,7 @@ static void led_work (struct work_struct *work)
changed++;
}
if (changed)
- queue_delayed_work(system_power_efficient_wq,
- &hub->leds, LED_CYCLE_PERIOD);
+ schedule_delayed_work(&hub->leds, LED_CYCLE_PERIOD);
}
/* use a short timeout for hub/port status fetches */
@@ -1080,9 +1079,8 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
if (hdev->bus->is_b_host)
goto init2;
#endif
- INIT_DELAYED_WORK(&hub->init_work, hub_init_func2);
- queue_delayed_work(system_power_efficient_wq,
- &hub->init_work,
+ PREPARE_DELAYED_WORK(&hub->init_work, hub_init_func2);
+ schedule_delayed_work(&hub->init_work,
msecs_to_jiffies(delay));
/* Suppress autosuspend until init is done */
@@ -1243,9 +1241,8 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
/* Don't do a long sleep inside a workqueue routine */
if (type == HUB_INIT2) {
- INIT_DELAYED_WORK(&hub->init_work, hub_init_func3);
- queue_delayed_work(system_power_efficient_wq,
- &hub->init_work,
+ PREPARE_DELAYED_WORK(&hub->init_work, hub_init_func3);
+ schedule_delayed_work(&hub->init_work,
msecs_to_jiffies(delay));
device_unlock(hub->intfdev);
return; /* Continues at init3: below */
@@ -1260,8 +1257,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
if (status < 0)
dev_err(hub->intfdev, "activate --> %d\n", status);
if (hub->has_indicators && blinkenlights)
- queue_delayed_work(system_power_efficient_wq,
- &hub->leds, LED_CYCLE_PERIOD);
+ schedule_delayed_work(&hub->leds, LED_CYCLE_PERIOD);
/* Scan all ports that need attention */
kick_khubd(hub);
@@ -4494,8 +4490,7 @@ check_highspeed (struct usb_hub *hub, struct usb_device *udev, int port1)
/* hub LEDs are probably harder to miss than syslog */
if (hub->has_indicators) {
hub->indicator[port1-1] = INDICATOR_GREEN_BLINK;
- queue_delayed_work(system_power_efficient_wq,
- &hub->leds, 0);
+ schedule_delayed_work (&hub->leds, 0);
}
}
kfree(qual);
@@ -4724,9 +4719,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
if (hub->has_indicators) {
hub->indicator[port1-1] =
INDICATOR_AMBER_BLINK;
- queue_delayed_work(
- system_power_efficient_wq,
- &hub->leds, 0);
+ schedule_delayed_work (&hub->leds, 0);
}
status = -ENOTCONN; /* Don't retry */
goto loop_disable;
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index d88a7b2dda6..ab21645e988 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2549,6 +2549,14 @@ static int __dwc3_cleanup_done_trbs(struct dwc3 *dwc, struct dwc3_ep *dep,
s_pkt = 1;
}
+ /*
+ * We assume here we will always receive the entire data block
+ * which we should receive. Meaning, if we program RX to
+ * receive 4K but we receive only 2K, we assume that's all we
+ * should receive and we simply bounce the request back to the
+ * gadget driver for further processing.
+ */
+ req->request.actual += length - count;
if (s_pkt)
return 1;
if ((event->status & DEPEVT_STATUS_LST) &&
@@ -2569,7 +2577,6 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
unsigned int slot;
unsigned int i;
unsigned int trb_len;
- int count = 0;
int ret;
do {
@@ -2598,8 +2605,6 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
slot++;
slot %= DWC3_TRB_NUM;
trb = &dep->trb_pool[slot];
- count += trb->size & DWC3_TRB_SIZE_MASK;
-
if (req->request.num_mapped_sgs)
trb_len = sg_dma_len(&req->request.sg[i]);
@@ -2612,14 +2617,6 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
break;
}while (++i < req->request.num_mapped_sgs);
- /*
- * We assume here we will always receive the entire data block
- * which we should receive. Meaning, if we program RX to
- * receive 4K but we receive only 2K, we assume that's all we
- * should receive and we simply bounce the request back to the
- * gadget driver for further processing.
- */
- req->request.actual += req->request.length - count;
if (req->ztrb) {
trb = req->ztrb;
if ((event->status & DEPEVT_STATUS_LST) &&
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index ef499470679..33da16834e4 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -1662,6 +1662,8 @@ static DEVICE_ATTR(suspended, 0444, composite_show_suspended, NULL);
static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver)
{
struct usb_composite_dev *cdev = get_gadget_data(gadget);
+ struct usb_gadget_strings *gstr = cdev->driver->strings[0];
+ struct usb_string *dev_str = gstr->strings;
/* composite_disconnect() must already have been called
* by the underlying peripheral controller driver!
@@ -1682,6 +1684,9 @@ static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver)
composite_dev_cleanup(cdev);
+ if (dev_str[USB_GADGET_MANUFACTURER_IDX].s == cdev->def_manufacturer)
+ dev_str[USB_GADGET_MANUFACTURER_IDX].s = "";
+
kfree(cdev->def_manufacturer);
kfree(cdev);
set_gadget_data(gadget, NULL);
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index 6656dfda566..0fa139081b1 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -1270,7 +1270,7 @@ static void set_td_timer(struct r8a66597 *r8a66597, struct r8a66597_td *td)
time = 30;
break;
default:
- time = 300;
+ time = 50;
break;
}
@@ -1786,6 +1786,7 @@ static void r8a66597_td_timer(unsigned long _r8a66597)
pipe = td->pipe;
pipe_stop(r8a66597, pipe);
+ /* Select a different address or endpoint */
new_td = td;
do {
list_move_tail(&new_td->queue,
@@ -1795,7 +1796,8 @@ static void r8a66597_td_timer(unsigned long _r8a66597)
new_td = td;
break;
}
- } while (td != new_td && td->address == new_td->address);
+ } while (td != new_td && td->address == new_td->address &&
+ td->pipe->info.epnum == new_td->pipe->info.epnum);
start_transfer(r8a66597, new_td);
diff --git a/drivers/usb/misc/ks_bridge.c b/drivers/usb/misc/ks_bridge.c
index 4018c6225df..cad74d62195 100644
--- a/drivers/usb/misc/ks_bridge.c
+++ b/drivers/usb/misc/ks_bridge.c
@@ -117,7 +117,7 @@ struct ks_bridge {
struct ks_bridge *__ksb[NO_BRIDGE_INSTANCES];
/* by default debugging is enabled */
-static unsigned int enable_dbg = 0;
+static unsigned int enable_dbg = 1;
module_param(enable_dbg, uint, S_IRUGO | S_IWUSR);
static void
diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c
index cfd205036ab..a4b02734258 100644
--- a/drivers/usb/renesas_usbhs/common.c
+++ b/drivers/usb/renesas_usbhs/common.c
@@ -600,8 +600,10 @@ static int usbhsc_resume(struct device *dev)
struct usbhs_priv *priv = dev_get_drvdata(dev);
struct platform_device *pdev = usbhs_priv_to_pdev(priv);
- if (!usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL))
+ if (!usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL)) {
usbhsc_power_ctrl(priv, 1);
+ usbhs_mod_autonomy_mode(priv);
+ }
usbhs_platform_call(priv, phy_reset, pdev);
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c
index 157a9f9afc2..0c962ff5eed 100644
--- a/drivers/usb/renesas_usbhs/fifo.c
+++ b/drivers/usb/renesas_usbhs/fifo.c
@@ -261,11 +261,26 @@ static void usbhsf_fifo_clear(struct usbhs_pipe *pipe,
struct usbhs_fifo *fifo)
{
struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
+ int ret = 0;
- if (!usbhs_pipe_is_dcp(pipe))
- usbhsf_fifo_barrier(priv, fifo);
+ if (!usbhs_pipe_is_dcp(pipe)) {
+ /*
+ * This driver checks the pipe condition first to avoid -EBUSY
+ * from usbhsf_fifo_barrier() with about 10 msec delay in
+ * the interrupt handler if the pipe is RX direction and empty.
+ */
+ if (usbhs_pipe_is_dir_in(pipe))
+ ret = usbhs_pipe_is_accessible(pipe);
+ if (!ret)
+ ret = usbhsf_fifo_barrier(priv, fifo);
+ }
- usbhs_write(priv, fifo->ctr, BCLR);
+ /*
+ * if non-DCP pipe, this driver should set BCLR when
+ * usbhsf_fifo_barrier() returns 0.
+ */
+ if (!ret)
+ usbhs_write(priv, fifo->ctr, BCLR);
}
static int usbhsf_fifo_rcv_len(struct usbhs_priv *priv,
@@ -545,6 +560,7 @@ static int usbhsf_pio_try_push(struct usbhs_pkt *pkt, int *is_done)
usbhsf_send_terminator(pipe, fifo);
usbhsf_tx_irq_ctrl(pipe, !*is_done);
+ usbhs_pipe_running(pipe, !*is_done);
usbhs_pipe_enable(pipe);
dev_dbg(dev, " send %d (%d/ %d/ %d/ %d)\n",
@@ -571,12 +587,21 @@ usbhs_fifo_write_busy:
* retry in interrupt
*/
usbhsf_tx_irq_ctrl(pipe, 1);
+ usbhs_pipe_running(pipe, 1);
return ret;
}
+static int usbhsf_pio_prepare_push(struct usbhs_pkt *pkt, int *is_done)
+{
+ if (usbhs_pipe_is_running(pkt->pipe))
+ return 0;
+
+ return usbhsf_pio_try_push(pkt, is_done);
+}
+
struct usbhs_pkt_handle usbhs_fifo_pio_push_handler = {
- .prepare = usbhsf_pio_try_push,
+ .prepare = usbhsf_pio_prepare_push,
.try_run = usbhsf_pio_try_push,
};
@@ -590,6 +615,9 @@ static int usbhsf_prepare_pop(struct usbhs_pkt *pkt, int *is_done)
if (usbhs_pipe_is_busy(pipe))
return 0;
+ if (usbhs_pipe_is_running(pipe))
+ return 0;
+
/*
* pipe enable to prepare packet receive
*/
@@ -598,6 +626,7 @@ static int usbhsf_prepare_pop(struct usbhs_pkt *pkt, int *is_done)
usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->length);
usbhs_pipe_enable(pipe);
+ usbhs_pipe_running(pipe, 1);
usbhsf_rx_irq_ctrl(pipe, 1);
return 0;
@@ -643,6 +672,7 @@ static int usbhsf_pio_try_pop(struct usbhs_pkt *pkt, int *is_done)
(total_len < maxp)) { /* short packet */
*is_done = 1;
usbhsf_rx_irq_ctrl(pipe, 0);
+ usbhs_pipe_running(pipe, 0);
usbhs_pipe_disable(pipe); /* disable pipe first */
}
@@ -798,10 +828,11 @@ static void xfer_work(struct work_struct *work)
dev_dbg(dev, " %s %d (%d/ %d)\n",
fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero);
+ usbhs_pipe_running(pipe, 1);
usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->trans);
- usbhs_pipe_enable(pipe);
- usbhsf_dma_start(pipe, fifo);
dma_async_issue_pending(chan);
+ usbhsf_dma_start(pipe, fifo);
+ usbhs_pipe_enable(pipe);
}
/*
@@ -829,6 +860,10 @@ static int usbhsf_dma_prepare_push(struct usbhs_pkt *pkt, int *is_done)
if ((uintptr_t)(pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */
goto usbhsf_pio_prepare_push;
+ /* return at this time if the pipe is running */
+ if (usbhs_pipe_is_running(pipe))
+ return 0;
+
/* get enable DMA fifo */
fifo = usbhsf_get_dma_fifo(priv, pkt);
if (!fifo)
@@ -866,6 +901,7 @@ static int usbhsf_dma_push_done(struct usbhs_pkt *pkt, int *is_done)
pkt->actual = pkt->trans;
*is_done = !pkt->zero; /* send zero packet ? */
+ usbhs_pipe_running(pipe, !*is_done);
usbhsf_dma_stop(pipe, pipe->fifo);
usbhsf_dma_unmap(pkt);
@@ -966,8 +1002,10 @@ static int usbhsf_dma_pop_done(struct usbhs_pkt *pkt, int *is_done)
if ((pkt->actual == pkt->length) || /* receive all data */
(pkt->trans < maxp)) { /* short packet */
*is_done = 1;
+ usbhs_pipe_running(pipe, 0);
} else {
/* re-enable */
+ usbhs_pipe_running(pipe, 0);
usbhsf_prepare_pop(pkt, is_done);
}
diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c
index 7926e1c700f..85e30e1d5e8 100644
--- a/drivers/usb/renesas_usbhs/pipe.c
+++ b/drivers/usb/renesas_usbhs/pipe.c
@@ -578,6 +578,19 @@ int usbhs_pipe_is_dir_host(struct usbhs_pipe *pipe)
return usbhsp_flags_has(pipe, IS_DIR_HOST);
}
+int usbhs_pipe_is_running(struct usbhs_pipe *pipe)
+{
+ return usbhsp_flags_has(pipe, IS_RUNNING);
+}
+
+void usbhs_pipe_running(struct usbhs_pipe *pipe, int running)
+{
+ if (running)
+ usbhsp_flags_set(pipe, IS_RUNNING);
+ else
+ usbhsp_flags_clr(pipe, IS_RUNNING);
+}
+
void usbhs_pipe_data_sequence(struct usbhs_pipe *pipe, int sequence)
{
u16 mask = (SQCLR | SQSET);
diff --git a/drivers/usb/renesas_usbhs/pipe.h b/drivers/usb/renesas_usbhs/pipe.h
index b476fde955b..b18a794922d 100644
--- a/drivers/usb/renesas_usbhs/pipe.h
+++ b/drivers/usb/renesas_usbhs/pipe.h
@@ -36,6 +36,7 @@ struct usbhs_pipe {
#define USBHS_PIPE_FLAGS_IS_USED (1 << 0)
#define USBHS_PIPE_FLAGS_IS_DIR_IN (1 << 1)
#define USBHS_PIPE_FLAGS_IS_DIR_HOST (1 << 2)
+#define USBHS_PIPE_FLAGS_IS_RUNNING (1 << 3)
struct usbhs_pkt_handle *handler;
@@ -79,6 +80,9 @@ int usbhs_pipe_probe(struct usbhs_priv *priv);
void usbhs_pipe_remove(struct usbhs_priv *priv);
int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe);
int usbhs_pipe_is_dir_host(struct usbhs_pipe *pipe);
+int usbhs_pipe_is_running(struct usbhs_pipe *pipe);
+void usbhs_pipe_running(struct usbhs_pipe *pipe, int running);
+
void usbhs_pipe_init(struct usbhs_priv *priv,
int (*dma_map_ctrl)(struct usbhs_pkt *pkt, int map));
int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe);
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c
index 5f3bcd31e20..f3bbe210119 100644
--- a/drivers/usb/serial/console.c
+++ b/drivers/usb/serial/console.c
@@ -188,6 +188,7 @@ static int usb_console_setup(struct console *co, char *options)
kfree(tty);
reset_open_count:
port->port.count = 0;
+ info->port = NULL;
usb_autopm_put_interface(serial->interface);
error_get_interface:
usb_serial_put(serial);
diff --git a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c
index 39b71e0ad0b..baed57d3cff 100644
--- a/drivers/video/cfbimgblt.c
+++ b/drivers/video/cfbimgblt.c
@@ -28,11 +28,6 @@
*
* Also need to add code to deal with cards endians that are different than
* the native cpu endians. I also need to deal with MSB position in the word.
- * Modified by Harm Hanemaaijer (fgenfb@yahoo.com) 2013:
- * - Provide optimized versions of fast_imageblit for 16 and 32bpp that are
- * significantly faster than the previous implementation.
- * - Simplify the fast/slow_imageblit selection code, avoiding integer
- * divides.
*/
#include <linux/module.h>
#include <linux/string.h>
@@ -267,133 +262,6 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info *
}
}
-/*
- * Optimized fast_imageblit for bpp == 16. ppw = 2, bit_mask = 3 folded
- * into the code, main loop unrolled.
- */
-
-static inline void fast_imageblit16(const struct fb_image *image,
- struct fb_info *p, u8 __iomem * dst1,
- u32 fgcolor, u32 bgcolor)
-{
- u32 fgx = fgcolor, bgx = bgcolor;
- u32 spitch = (image->width + 7) / 8;
- u32 end_mask, eorx;
- const char *s = image->data, *src;
- u32 __iomem *dst;
- const u32 *tab = NULL;
- int i, j, k;
-
- tab = fb_be_math(p) ? cfb_tab16_be : cfb_tab16_le;
-
- fgx <<= 16;
- bgx <<= 16;
- fgx |= fgcolor;
- bgx |= bgcolor;
-
- eorx = fgx ^ bgx;
- k = image->width / 2;
-
- for (i = image->height; i--;) {
- dst = (u32 __iomem *) dst1;
- src = s;
-
- j = k;
- while (j >= 4) {
- u8 bits = *src;
- end_mask = tab[(bits >> 6) & 3];
- FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
- end_mask = tab[(bits >> 4) & 3];
- FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
- end_mask = tab[(bits >> 2) & 3];
- FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
- end_mask = tab[bits & 3];
- FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
- src++;
- j -= 4;
- }
- if (j != 0) {
- u8 bits = *src;
- end_mask = tab[(bits >> 6) & 3];
- FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
- if (j >= 2) {
- end_mask = tab[(bits >> 4) & 3];
- FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
- if (j == 3) {
- end_mask = tab[(bits >> 2) & 3];
- FB_WRITEL((end_mask & eorx) ^ bgx, dst);
- }
- }
- }
- dst1 += p->fix.line_length;
- s += spitch;
- }
-}
-
-/*
- * Optimized fast_imageblit for bpp == 32. ppw = 1, bit_mask = 1 folded
- * into the code, main loop unrolled.
- */
-
-static inline void fast_imageblit32(const struct fb_image *image,
- struct fb_info *p, u8 __iomem * dst1,
- u32 fgcolor, u32 bgcolor)
-{
- u32 fgx = fgcolor, bgx = bgcolor;
- u32 spitch = (image->width + 7) / 8;
- u32 end_mask, eorx;
- const char *s = image->data, *src;
- u32 __iomem *dst;
- const u32 *tab = NULL;
- int i, j, k;
-
- tab = cfb_tab32;
-
- eorx = fgx ^ bgx;
- k = image->width;
-
- for (i = image->height; i--;) {
- dst = (u32 __iomem *) dst1;
- src = s;
-
- j = k;
- while (j >= 8) {
- u8 bits = *src;
- end_mask = tab[(bits >> 7) & 1];
- FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
- end_mask = tab[(bits >> 6) & 1];
- FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
- end_mask = tab[(bits >> 5) & 1];
- FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
- end_mask = tab[(bits >> 4) & 1];
- FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
- end_mask = tab[(bits >> 3) & 1];
- FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
- end_mask = tab[(bits >> 2) & 1];
- FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
- end_mask = tab[(bits >> 1) & 1];
- FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
- end_mask = tab[bits & 1];
- FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
- src++;
- j -= 8;
- }
- if (j != 0) {
- u32 bits = (u32) * src;
- while (j > 1) {
- end_mask = tab[(bits >> 7) & 1];
- FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
- bits <<= 1;
- j--;
- }
- end_mask = tab[(bits >> 7) & 1];
- FB_WRITEL((end_mask & eorx) ^ bgx, dst);
- }
- dst1 += p->fix.line_length;
- s += spitch;
- }
-}
-
void cfb_imageblit(struct fb_info *p, const struct fb_image *image)
{
u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0;
@@ -426,21 +294,11 @@ void cfb_imageblit(struct fb_info *p, const struct fb_image *image)
bgcolor = image->bg_color;
}
- if (!start_index && !pitch_index) {
- if (bpp == 32)
- fast_imageblit32(image, p, dst1, fgcolor,
- bgcolor);
- else if (bpp == 16 && (width & 1) == 0)
- fast_imageblit16(image, p, dst1, fgcolor,
- bgcolor);
- else if (bpp == 8 && (width & 3) == 0)
- fast_imageblit(image, p, dst1, fgcolor,
- bgcolor);
- else
- slow_imageblit(image, p, dst1, fgcolor,
- bgcolor,
- start_index, pitch_index);
- } else
+ if (32 % bpp == 0 && !start_index && !pitch_index &&
+ ((width & (32/bpp-1)) == 0) &&
+ bpp >= 8 && bpp <= 32)
+ fast_imageblit(image, p, dst1, fgcolor, bgcolor);
+ else
slow_imageblit(image, p, dst1, fgcolor, bgcolor,
start_index, pitch_index);
} else
@@ -453,4 +311,3 @@ MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>");
MODULE_DESCRIPTION("Generic software accelerated imaging drawing");
MODULE_LICENSE("GPL");
-
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index e3a9fb5bd2f..e432d363db6 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1087,6 +1087,13 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
void __user *argp = (void __user *)arg;
long ret = 0;
+ memset(&var, 0, sizeof(var));
+ memset(&fix, 0, sizeof(fix));
+ memset(&con2fb, 0, sizeof(con2fb));
+ memset(&cmap_from, 0, sizeof(cmap_from));
+ memset(&cmap, 0, sizeof(cmap));
+ memset(&event, 0, sizeof(event));
+
switch (cmd) {
case FBIOGET_VSCREENINFO:
if (!lock_fb_info(info))
diff --git a/drivers/video/msm/mdss/mdp3_ppp.c b/drivers/video/msm/mdss/mdp3_ppp.c
index 772ee197785..2e8cb4e46ca 100644
--- a/drivers/video/msm/mdss/mdp3_ppp.c
+++ b/drivers/video/msm/mdss/mdp3_ppp.c
@@ -37,6 +37,7 @@
#define MDP_PPP_MAX_BPP 4
#define MDP_PPP_DYNAMIC_FACTOR 3
#define MDP_PPP_MAX_READ_WRITE 3
+#define MDP_PPP_MAX_WIDTH 0xFFF
#define ENABLE_SOLID_FILL 0x2
#define DISABLE_SOLID_FILL 0x0
#define BLEND_LATENCY 3
@@ -148,6 +149,11 @@ int mdp3_ppp_get_img(struct mdp_img *img, struct mdp_blit_req *req,
return -EINVAL;
}
+ if (img->width > MDP_PPP_MAX_WIDTH) {
+ pr_err("%s incorrect width %d\n", __func__, img->width);
+ return -EINVAL;
+ }
+
fb_data.flags = img->priv;
fb_data.memory_id = img->memory_id;
fb_data.offset = 0;
diff --git a/drivers/video/msm/mdss/mdss_edp.c b/drivers/video/msm/mdss/mdss_edp.c
index 668522527bd..1ed8eabdcb3 100644
--- a/drivers/video/msm/mdss/mdss_edp.c
+++ b/drivers/video/msm/mdss/mdss_edp.c
@@ -897,20 +897,11 @@ static int edp_event_thread(void *data)
struct mdss_edp_drv_pdata *ep;
unsigned long flag;
u32 todo = 0;
- int ret;
ep = (struct mdss_edp_drv_pdata *)data;
while (1) {
- ret = wait_event_interruptible(ep->event_q,
- (ep->event_pndx != ep->event_gndx) ||
- kthread_should_stop());
-
- if (ret) {
- pr_debug("%s: interrupted", __func__);
- continue;
- }
-
+ wait_event(ep->event_q, (ep->event_pndx != ep->event_gndx));
spin_lock_irqsave(&ep->event_lock, flag);
if (ep->event_pndx == ep->event_gndx) {
spin_unlock_irqrestore(&ep->event_lock, flag);
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index 21e2e60a61a..be86411ec38 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -3348,6 +3348,7 @@ static void mdss_fb_var_to_panelinfo(struct fb_var_screeninfo *var,
static void mdss_panelinfo_to_fb_var(struct mdss_panel_info *pinfo,
struct fb_var_screeninfo *var)
{
+ u32 frame_rate;
struct mdss_panel_data *pdata = container_of(pinfo,
struct mdss_panel_data, panel_info);
@@ -3359,7 +3360,21 @@ static void mdss_panelinfo_to_fb_var(struct mdss_panel_info *pinfo,
var->right_margin = pinfo->lcdc.h_front_porch;
var->left_margin = pinfo->lcdc.h_back_porch;
var->hsync_len = pinfo->lcdc.h_pulse_width;
- var->pixclock = pinfo->clk_rate;
+
+ frame_rate = mdss_panel_get_framerate(pinfo);
+ if (frame_rate) {
+ unsigned long clk_rate, h_total, v_total;
+
+ h_total = var->xres + var->left_margin
+ + var->right_margin + var->hsync_len;
+ v_total = var->yres + var->lower_margin
+ + var->upper_margin + var->vsync_len;
+ clk_rate = h_total * v_total * frame_rate;
+ var->pixclock = KHZ2PICOS(clk_rate / 1000);
+ } else if (pinfo->clk_rate) {
+ var->pixclock = KHZ2PICOS(
+ (unsigned long int) pinfo->clk_rate / 1000);
+ }
}
/**
@@ -3446,15 +3461,10 @@ static int __mdss_fb_display_thread(void *data)
mfd->index);
while (1) {
- ret = wait_event_interruptible(mfd->commit_wait_q,
+ wait_event(mfd->commit_wait_q,
(atomic_read(&mfd->commits_pending) ||
kthread_should_stop()));
- if (ret) {
- pr_info("%s: interrupted", __func__);
- continue;
- }
-
if (kthread_should_stop())
break;
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_video.c b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
index 0db7286d59a..27737f081e8 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_video.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1196,8 +1196,9 @@ static void mdss_mdp_handoff_programmable_fetch(struct mdss_mdp_ctl *ctl,
MDSS_MDP_REG_INTF_HSYNC_CTL) >> 16;
v_total_handoff = mdp_video_read(ctx,
MDSS_MDP_REG_INTF_VSYNC_PERIOD_F0)/h_total_handoff;
- ctl->prg_fet = v_total_handoff -
- ((fetch_start_handoff - 1)/h_total_handoff);
+ if (h_total_handoff)
+ ctl->prg_fet = v_total_handoff -
+ ((fetch_start_handoff - 1)/h_total_handoff);
pr_debug("programmable fetch lines %d start:%d\n",
ctl->prg_fet, fetch_start_handoff);
}
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index 2400e149345..f41390a5069 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -3854,6 +3854,11 @@ static int mdss_mdp_hw_cursor_update(struct msm_fb_data_type *mfd,
if (cursor->set & FB_CUR_SETIMAGE) {
u32 cursor_addr;
+ if (img->width * img->height * 4 > cursor_frame_size) {
+ pr_err("cursor image size is too large\n");
+ ret = -EINVAL;
+ goto done;
+ }
ret = copy_from_user(mfd->cursor_buf, img->data,
img->width * img->height * 4);
if (ret) {
@@ -4191,12 +4196,16 @@ static int mdss_fb_get_metadata(struct msm_fb_data_type *mfd,
ret = mdss_fb_get_hw_caps(mfd, &metadata->data.caps);
break;
case metadata_op_get_ion_fd:
- if (mfd->fb_ion_handle) {
+ if (mfd->fb_ion_handle && mfd->fb_ion_client) {
+ get_dma_buf(mfd->fbmem_buf);
metadata->data.fbmem_ionfd =
- dma_buf_fd(mfd->fbmem_buf, 0);
- if (metadata->data.fbmem_ionfd < 0)
+ ion_share_dma_buf_fd(mfd->fb_ion_client,
+ mfd->fb_ion_handle);
+ if (metadata->data.fbmem_ionfd < 0) {
+ dma_buf_put(mfd->fbmem_buf);
pr_err("fd allocation failed. fd = %d\n",
metadata->data.fbmem_ionfd);
+ }
}
break;
case metadata_op_crc:
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index 5cbf523472e..b092728525f 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -5916,9 +5916,6 @@ static int is_valid_calib_addr(void *addr, u32 operation)
int ret = 0;
char __iomem *ptr = addr;
char __iomem *mixer_base = mdss_res->mixer_intf->base;
- char __iomem *rgb_base = mdss_res->rgb_pipes->base;
- char __iomem *dma_base = mdss_res->dma_pipes->base;
- char __iomem *vig_base = mdss_res->vig_pipes->base;
char __iomem *ctl_base = mdss_res->ctl_off->base;
char __iomem *dspp_base = mdss_res->mixer_intf->dspp_base;
@@ -5950,17 +5947,20 @@ static int is_valid_calib_addr(void *addr, u32 operation)
if (ret)
goto valid_addr;
}
- if (ptr >= vig_base) {
+ if (mdss_res->vig_pipes &&
+ ptr >= mdss_res->vig_pipes->base) {
ret = is_valid_calib_vig_addr(ptr);
if (ret)
goto valid_addr;
}
- if (ptr >= rgb_base) {
+ if (mdss_res->rgb_pipes &&
+ ptr >= mdss_res->rgb_pipes->base) {
ret = is_valid_calib_rgb_addr(ptr);
if (ret)
goto valid_addr;
}
- if (ptr >= dma_base) {
+ if (mdss_res->dma_pipes &&
+ ptr >= mdss_res->dma_pipes->base) {
ret = is_valid_calib_dma_addr(ptr);
if (ret)
goto valid_addr;
diff --git a/fs/9p/acl.c b/fs/9p/acl.c
index c19a66472d2..6b951d1140d 100644
--- a/fs/9p/acl.c
+++ b/fs/9p/acl.c
@@ -323,7 +323,8 @@ static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name,
struct iattr iattr;
struct posix_acl *old_acl = acl;
- retval = posix_acl_update_mode(inode, &iattr.ia_mode, &acl);
+ retval = posix_acl_update_mode(inode,
+ &iattr.ia_mode, &acl);
if (retval)
goto err_out;
if (!acl) {
diff --git a/fs/aio.c b/fs/aio.c
index 3cad01eb0b4..0f2c38f29c4 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1161,6 +1161,7 @@ long do_io_submit(aio_context_t ctx_id, long nr,
struct kioctx *ctx;
long ret = 0;
int i = 0;
+ struct blk_plug plug;
if (unlikely(nr < 0))
return -EINVAL;
@@ -1177,6 +1178,8 @@ long do_io_submit(aio_context_t ctx_id, long nr,
return -EINVAL;
}
+ blk_start_plug(&plug);
+
/*
* AKPM: should this return a partial result if some of the IOs were
* successfully submitted?
@@ -1199,6 +1202,7 @@ long do_io_submit(aio_context_t ctx_id, long nr,
if (ret)
break;
}
+ blk_finish_plug(&plug);
put_ioctx(ctx);
return i ? i : ret;
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c
index d6d53e5e794..1fc4626becc 100644
--- a/fs/btrfs/acl.c
+++ b/fs/btrfs/acl.c
@@ -118,7 +118,8 @@ static int btrfs_set_acl(struct btrfs_trans_handle *trans,
case ACL_TYPE_ACCESS:
name = POSIX_ACL_XATTR_ACCESS;
if (acl) {
- ret = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+ ret = posix_acl_update_mode(inode,
+ &inode->i_mode, &acl);
if (ret)
return ret;
}
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 296cc1b4944..7831e6865f1 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -2974,6 +2974,10 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp)
ret = PTR_ERR(new_root);
goto out;
}
+ if (!is_fstree(new_root->objectid)) {
+ ret = -ENOENT;
+ goto out;
+ }
if (btrfs_root_refs(&new_root->root_item) == 0) {
ret = -ENOENT;
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 0fe3d65403d..1396937f715 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -774,7 +774,8 @@ out:
*/
if (sdio->boundary) {
ret = dio_send_cur_page(dio, sdio, map_bh);
- dio_bio_submit(dio, sdio);
+ if (sdio->bio)
+ dio_bio_submit(dio, sdio);
page_cache_release(sdio->cur_page);
sdio->cur_page = NULL;
}
@@ -948,6 +949,7 @@ do_holes:
i_size_aligned >> blkbits) {
/* We hit eof */
page_cache_release(page);
+ dio_cleanup(dio, sdio);
goto out;
}
zero_user(page, block_in_page << blkbits,
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index deecc7294a6..0cff4434880 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -34,6 +34,7 @@
#include <linux/mutex.h>
#include <linux/anon_inodes.h>
#include <linux/device.h>
+#include <linux/freezer.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/mman.h>
@@ -1602,7 +1603,8 @@ fetch_events:
}
spin_unlock_irqrestore(&ep->lock, flags);
- if (!schedule_hrtimeout_range(to, slack, HRTIMER_MODE_ABS))
+ if (!freezable_schedule_hrtimeout_range(to, slack,
+ HRTIMER_MODE_ABS))
timed_out = 1;
spin_lock_irqsave(&ep->lock, flags);
diff --git a/fs/exec.c b/fs/exec.c
index 0b31a8040c6..d84c14880e1 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -197,8 +197,26 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
if (write) {
unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start;
+ unsigned long ptr_size;
struct rlimit *rlim;
+ /*
+ * Since the stack will hold pointers to the strings, we
+ * must account for them as well.
+ *
+ * The size calculation is the entire vma while each arg page is
+ * built, so each time we get here it's calculating how far it
+ * is currently (rather than each call being just the newly
+ * added size from the arg page). As a result, we need to
+ * always add the entire size of the pointers, so that on the
+ * last call to get_arg_page() we'll actually have the entire
+ * correct size.
+ */
+ ptr_size = (bprm->argc + bprm->envc) * sizeof(void *);
+ if (ptr_size > ULONG_MAX - size)
+ goto fail;
+ size += ptr_size;
+
acct_arg_size(bprm, size / PAGE_SIZE);
/*
@@ -216,13 +234,15 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
* to work from.
*/
rlim = current->signal->rlim;
- if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur) / 4) {
- put_page(page);
- return NULL;
- }
+ if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur) / 4)
+ goto fail;
}
return page;
+
+fail:
+ put_page(page);
+ return NULL;
}
static void put_arg_page(struct page *page)
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c
index 48c3c2d7d26..36ad07b03e0 100644
--- a/fs/ext2/acl.c
+++ b/fs/ext2/acl.c
@@ -206,7 +206,8 @@ ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
case ACL_TYPE_ACCESS:
name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS;
if (acl) {
- error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+ error = posix_acl_update_mode(inode,
+ &inode->i_mode, &acl);
if (error)
return error;
inode->i_ctime = CURRENT_TIME_SEC;
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c
index bb2f60a62d8..dbb5ad59a7f 100644
--- a/fs/ext3/acl.c
+++ b/fs/ext3/acl.c
@@ -205,11 +205,15 @@ ext3_set_acl(handle_t *handle, struct inode *inode, int type,
case ACL_TYPE_ACCESS:
name_index = EXT3_XATTR_INDEX_POSIX_ACL_ACCESS;
if (acl) {
- error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
- if (error)
+ error = posix_acl_equiv_mode(acl, &inode->i_mode);
+ if (error < 0)
return error;
- inode->i_ctime = CURRENT_TIME_SEC;
- ext3_mark_inode_dirty(handle, inode);
+ else {
+ inode->i_ctime = CURRENT_TIME_SEC;
+ ext3_mark_inode_dirty(handle, inode);
+ if (error == 0)
+ acl = NULL;
+ }
}
break;
diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig
index efea5d5c44c..af1a90a8b22 100644
--- a/fs/ext4/Kconfig
+++ b/fs/ext4/Kconfig
@@ -64,6 +64,24 @@ config EXT4_FS_SECURITY
If you are not using a security module that requires using
extended attributes for file security labels, say N.
+config EXT4_FS_ENCRYPTION
+ bool "Ext4 Encryption"
+ depends on EXT4_FS
+ select CRYPTO_AES
+ select CRYPTO_CBC
+ select CRYPTO_ECB
+ select CRYPTO_XTS
+ select CRYPTO_CTS
+ select CRYPTO_CTR
+ select CRYPTO_SHA256
+ select KEYS
+ select ENCRYPTED_KEYS
+ help
+ Enable encryption of ext4 files and directories. This
+ feature is similar to ecryptfs, but it is more memory
+ efficient since it avoids caching the encrypted and
+ decrypted pages in the page cache.
+
config EXT4_DEBUG
bool "EXT4 debugging support"
depends on EXT4_FS
diff --git a/fs/ext4/Makefile b/fs/ext4/Makefile
index 0310fec2ee3..cd6f50fce27 100644
--- a/fs/ext4/Makefile
+++ b/fs/ext4/Makefile
@@ -8,7 +8,7 @@ ext4-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o page-io.o \
ioctl.o namei.o super.o symlink.o hash.o resize.o extents.o \
ext4_jbd2.o migrate.o mballoc.o block_validity.o move_extent.o \
mmp.o indirect.o extents_status.o xattr.o xattr_user.o \
- xattr_trusted.o inline.o
+ xattr_trusted.o inline.o readpage.o
ext4-$(CONFIG_EXT4_FS_POSIX_ACL) += acl.o
ext4-$(CONFIG_EXT4_FS_SECURITY) += xattr_security.o
diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c
index c844f1bfb45..9bbdc384768 100644
--- a/fs/ext4/acl.c
+++ b/fs/ext4/acl.c
@@ -211,7 +211,8 @@ ext4_set_acl(handle_t *handle, struct inode *inode, int type,
case ACL_TYPE_ACCESS:
name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS;
if (acl) {
- error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+ error = posix_acl_update_mode(inode,
+ &inode->i_mode, &acl);
if (error)
return error;
inode->i_ctime = ext4_current_time(inode);
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 79b9210c119..2e8b010aff7 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -246,6 +246,7 @@ struct ext4_io_submit {
#define EXT4_MAX_BLOCK_SIZE 65536
#define EXT4_MIN_BLOCK_LOG_SIZE 10
#define EXT4_MAX_BLOCK_LOG_SIZE 16
+#define EXT4_MAX_CLUSTER_LOG_SIZE 30
#ifdef __KERNEL__
# define EXT4_BLOCK_SIZE(s) ((s)->s_blocksize)
#else
@@ -2651,6 +2652,10 @@ static inline void ext4_set_de_type(struct super_block *sb,
de->file_type = ext4_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
}
+/* readpages.c */
+extern int ext4_mpage_readpages(struct address_space *mapping,
+ struct list_head *pages, struct page *page,
+ unsigned nr_pages);
/* symlink.c */
extern const struct inode_operations ext4_symlink_inode_operations;
diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c
index 3517d5af257..1be3996b594 100644
--- a/fs/ext4/ext4_jbd2.c
+++ b/fs/ext4/ext4_jbd2.c
@@ -75,14 +75,8 @@ int __ext4_journal_stop(const char *where, unsigned int line, handle_t *handle)
ext4_put_nojournal(handle);
return 0;
}
-
- err = handle->h_err;
- if (!handle->h_transaction) {
- rc = jbd2_journal_stop(handle);
- return err ? err : rc;
- }
-
sb = handle->h_transaction->t_journal->j_private;
+ err = handle->h_err;
rc = jbd2_journal_stop(handle);
if (!err)
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index ec9770f4253..ed2badabebf 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -325,47 +325,27 @@ static int ext4_find_unwritten_pgoff(struct inode *inode,
num = min_t(pgoff_t, end - index, PAGEVEC_SIZE);
nr_pages = pagevec_lookup(&pvec, inode->i_mapping, index,
(pgoff_t)num);
- if (nr_pages == 0) {
- if (whence == SEEK_DATA)
- break;
-
- BUG_ON(whence != SEEK_HOLE);
- /*
- * If this is the first time to go into the loop and
- * offset is not beyond the end offset, it will be a
- * hole at this offset
- */
- if (lastoff == startoff || lastoff < endoff)
- found = 1;
+ if (nr_pages == 0)
break;
- }
-
- /*
- * If this is the first time to go into the loop and
- * offset is smaller than the first page offset, it will be a
- * hole at this offset.
- */
- if (lastoff == startoff && whence == SEEK_HOLE &&
- lastoff < page_offset(pvec.pages[0])) {
- found = 1;
- break;
- }
for (i = 0; i < nr_pages; i++) {
struct page *page = pvec.pages[i];
struct buffer_head *bh, *head;
/*
- * If the current offset is not beyond the end of given
- * range, it will be a hole.
+ * If current offset is smaller than the page offset,
+ * there is a hole at this offset.
*/
- if (lastoff < endoff && whence == SEEK_HOLE &&
- page->index > end) {
+ if (whence == SEEK_HOLE && lastoff < endoff &&
+ lastoff < page_offset(pvec.pages[i])) {
found = 1;
*offset = lastoff;
goto out;
}
+ if (page->index > end)
+ goto out;
+
lock_page(page);
if (unlikely(page->mapping != inode->i_mapping)) {
@@ -382,6 +362,8 @@ static int ext4_find_unwritten_pgoff(struct inode *inode,
lastoff = page_offset(page);
bh = head = page_buffers(page);
do {
+ if (lastoff + bh->b_size <= startoff)
+ goto next;
if (buffer_uptodate(bh) ||
buffer_unwritten(bh)) {
if (whence == SEEK_DATA)
@@ -396,6 +378,7 @@ static int ext4_find_unwritten_pgoff(struct inode *inode,
unlock_page(page);
goto out;
}
+next:
lastoff += bh->b_size;
bh = bh->b_this_page;
} while (bh != head);
@@ -405,20 +388,18 @@ static int ext4_find_unwritten_pgoff(struct inode *inode,
unlock_page(page);
}
- /*
- * The no. of pages is less than our desired, that would be a
- * hole in there.
- */
- if (nr_pages < num && whence == SEEK_HOLE) {
- found = 1;
- *offset = lastoff;
+ /* The no. of pages is less than our desired, we are done. */
+ if (nr_pages < num)
break;
- }
index = pvec.pages[i - 1]->index + 1;
pagevec_release(&pvec);
} while (index <= end);
+ if (whence == SEEK_HOLE && lastoff < endoff) {
+ found = 1;
+ *offset = lastoff;
+ }
out:
pagevec_release(&pvec);
return found;
@@ -440,7 +421,7 @@ static loff_t ext4_seek_data(struct file *file, loff_t offset, loff_t maxsize)
mutex_lock(&inode->i_mutex);
isize = i_size_read(inode);
- if (offset >= isize) {
+ if (offset < 0 || offset >= isize) {
mutex_unlock(&inode->i_mutex);
return -ENXIO;
}
@@ -523,7 +504,7 @@ static loff_t ext4_seek_hole(struct file *file, loff_t offset, loff_t maxsize)
mutex_lock(&inode->i_mutex);
isize = i_size_read(inode);
- if (offset >= isize) {
+ if (offset < 0 || offset >= isize) {
mutex_unlock(&inode->i_mutex);
return -ENXIO;
}
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 6bcadebeef2..6d5f9690fc2 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3015,7 +3015,7 @@ static int ext4_readpage(struct file *file, struct page *page)
ret = ext4_readpage_inline(inode, page);
if (ret == -EAGAIN)
- return mpage_readpage(page, ext4_get_block);
+ return ext4_mpage_readpages(page->mapping, NULL, page, 1);
return ret;
}
@@ -3030,7 +3030,7 @@ ext4_readpages(struct file *file, struct address_space *mapping,
if (ext4_has_inline_data(inode))
return 0;
- return mpage_readpages(mapping, pages, nr_pages, ext4_get_block);
+ return ext4_mpage_readpages(mapping, pages, NULL, nr_pages);
}
static void ext4_invalidatepage(struct page *page, unsigned long offset)
@@ -5061,8 +5061,9 @@ static int ext4_expand_extra_isize(struct inode *inode,
/* No extended attributes present */
if (!ext4_test_inode_state(inode, EXT4_STATE_XATTR) ||
header->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC)) {
- memset((void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE, 0,
- new_extra_isize);
+ memset((void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE +
+ EXT4_I(inode)->i_extra_isize, 0,
+ new_extra_isize - EXT4_I(inode)->i_extra_isize);
EXT4_I(inode)->i_extra_isize = new_extra_isize;
return 0;
}
@@ -5113,8 +5114,6 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
sbi->s_want_extra_isize,
iloc, handle);
if (ret) {
- ext4_set_inode_state(inode,
- EXT4_STATE_NO_EXPAND);
if (mnt_count !=
le16_to_cpu(sbi->s_es->s_mnt_count)) {
ext4_warning(inode->i_sb,
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 407bcf79aa3..55014e9603e 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -2253,9 +2253,20 @@ retry:
inode->i_op = &ext4_file_inode_operations;
inode->i_fop = &ext4_file_operations;
ext4_set_aops(inode);
- err = ext4_add_nondir(handle, dentry, inode);
+ err = 0;
+#ifdef CONFIG_EXT4_FS_ENCRYPTION
+ if (!err && ext4_encrypted_inode(dir))
+ err = ext4_inherit_context(dir, inode);
+#endif
+ if (!err)
+ err = ext4_add_nondir(handle, dentry, inode);
if (!err && IS_DIRSYNC(dir))
ext4_handle_sync(handle);
+ if (err) {
+ clear_nlink(inode);
+ unlock_new_inode(inode);
+ iput(inode);
+ }
}
if (handle)
ext4_journal_stop(handle);
@@ -2401,6 +2412,13 @@ retry:
err = ext4_init_new_dir(handle, dir, inode);
if (err)
goto out_clear_inode;
+#ifdef CONFIG_EXT4_FS_ENCRYPTION
+ if (ext4_encrypted_inode(dir)) {
+ err = ext4_inherit_context(dir, inode);
+ if (err)
+ goto out_clear_inode;
+ }
+#endif
err = ext4_mark_inode_dirty(handle, inode);
if (!err)
err = ext4_add_entry(handle, dentry, inode);
diff --git a/fs/ext4/readpage.c b/fs/ext4/readpage.c
new file mode 100644
index 00000000000..ae7c56984e3
--- /dev/null
+++ b/fs/ext4/readpage.c
@@ -0,0 +1,264 @@
+/*
+ * linux/fs/ext4/readpage.c
+ *
+ * Copyright (C) 2002, Linus Torvalds.
+ * Copyright (C) 2015, Google, Inc.
+ *
+ * This was originally taken from fs/mpage.c
+ *
+ * The intent is the ext4_mpage_readpages() function here is intended
+ * to replace mpage_readpages() in the general case, not just for
+ * encrypted files. It has some limitations (see below), where it
+ * will fall back to read_block_full_page(), but these limitations
+ * should only be hit when page_size != block_size.
+ *
+ * This will allow us to attach a callback function to support ext4
+ * encryption.
+ *
+ * If anything unusual happens, such as:
+ *
+ * - encountering a page which has buffers
+ * - encountering a page which has a non-hole after a hole
+ * - encountering a page with non-contiguous blocks
+ *
+ * then this code just gives up and calls the buffer_head-based read function.
+ * It does handle a page which has holes at the end - that is a common case:
+ * the end-of-file on blocksize < PAGE_CACHE_SIZE setups.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/export.h>
+#include <linux/mm.h>
+#include <linux/kdev_t.h>
+#include <linux/gfp.h>
+#include <linux/bio.h>
+#include <linux/fs.h>
+#include <linux/buffer_head.h>
+#include <linux/blkdev.h>
+#include <linux/highmem.h>
+#include <linux/prefetch.h>
+#include <linux/mpage.h>
+#include <linux/writeback.h>
+#include <linux/backing-dev.h>
+#include <linux/pagevec.h>
+#include <linux/cleancache.h>
+
+#include "ext4.h"
+
+/*
+ * I/O completion handler for multipage BIOs.
+ *
+ * The mpage code never puts partial pages into a BIO (except for end-of-file).
+ * If a page does not map to a contiguous run of blocks then it simply falls
+ * back to block_read_full_page().
+ *
+ * Why is this? If a page's completion depends on a number of different BIOs
+ * which can complete in any order (or at the same time) then determining the
+ * status of that page is hard. See end_buffer_async_read() for the details.
+ * There is no point in duplicating all that complexity.
+ */
+static void mpage_end_io(struct bio *bio, int err)
+{
+ struct bio_vec *bv;
+ int i;
+
+ bio_for_each_segment_all(bv, bio, i) {
+ struct page *page = bv->bv_page;
+
+ if (!err) {
+ SetPageUptodate(page);
+ } else {
+ ClearPageUptodate(page);
+ SetPageError(page);
+ }
+ unlock_page(page);
+ }
+
+ bio_put(bio);
+}
+
+int ext4_mpage_readpages(struct address_space *mapping,
+ struct list_head *pages, struct page *page,
+ unsigned nr_pages)
+{
+ struct bio *bio = NULL;
+ unsigned page_idx;
+ sector_t last_block_in_bio = 0;
+
+ struct inode *inode = mapping->host;
+ const unsigned blkbits = inode->i_blkbits;
+ const unsigned blocks_per_page = PAGE_CACHE_SIZE >> blkbits;
+ const unsigned blocksize = 1 << blkbits;
+ sector_t block_in_file;
+ sector_t last_block;
+ sector_t last_block_in_file;
+ sector_t blocks[MAX_BUF_PER_PAGE];
+ unsigned page_block;
+ struct block_device *bdev = inode->i_sb->s_bdev;
+ int length;
+ unsigned relative_block = 0;
+ struct ext4_map_blocks map;
+
+ map.m_pblk = 0;
+ map.m_lblk = 0;
+ map.m_len = 0;
+ map.m_flags = 0;
+
+ for (page_idx = 0; nr_pages; page_idx++, nr_pages--) {
+ int fully_mapped = 1;
+ unsigned first_hole = blocks_per_page;
+
+ prefetchw(&page->flags);
+ if (pages) {
+ page = list_entry(pages->prev, struct page, lru);
+ list_del(&page->lru);
+ if (add_to_page_cache_lru(page, mapping,
+ page->index, GFP_KERNEL))
+ goto next_page;
+ }
+
+ if (page_has_buffers(page))
+ goto confused;
+
+ block_in_file = (sector_t)page->index << (PAGE_CACHE_SHIFT - blkbits);
+ last_block = block_in_file + nr_pages * blocks_per_page;
+ last_block_in_file = (i_size_read(inode) + blocksize - 1) >> blkbits;
+ if (last_block > last_block_in_file)
+ last_block = last_block_in_file;
+ page_block = 0;
+
+ /*
+ * Map blocks using the previous result first.
+ */
+ if ((map.m_flags & EXT4_MAP_MAPPED) &&
+ block_in_file > map.m_lblk &&
+ block_in_file < (map.m_lblk + map.m_len)) {
+ unsigned map_offset = block_in_file - map.m_lblk;
+ unsigned last = map.m_len - map_offset;
+
+ for (relative_block = 0; ; relative_block++) {
+ if (relative_block == last) {
+ /* needed? */
+ map.m_flags &= ~EXT4_MAP_MAPPED;
+ break;
+ }
+ if (page_block == blocks_per_page)
+ break;
+ blocks[page_block] = map.m_pblk + map_offset +
+ relative_block;
+ page_block++;
+ block_in_file++;
+ }
+ }
+
+ /*
+ * Then do more ext4_map_blocks() calls until we are
+ * done with this page.
+ */
+ while (page_block < blocks_per_page) {
+ if (block_in_file < last_block) {
+ map.m_lblk = block_in_file;
+ map.m_len = last_block - block_in_file;
+
+ if (ext4_map_blocks(NULL, inode, &map, 0) < 0) {
+ set_error_page:
+ SetPageError(page);
+ zero_user_segment(page, 0,
+ PAGE_CACHE_SIZE);
+ unlock_page(page);
+ goto next_page;
+ }
+ }
+ if ((map.m_flags & EXT4_MAP_MAPPED) == 0) {
+ fully_mapped = 0;
+ if (first_hole == blocks_per_page)
+ first_hole = page_block;
+ page_block++;
+ block_in_file++;
+ continue;
+ }
+ if (first_hole != blocks_per_page)
+ goto confused; /* hole -> non-hole */
+
+ /* Contiguous blocks? */
+ if (page_block && blocks[page_block-1] != map.m_pblk-1)
+ goto confused;
+ for (relative_block = 0; ; relative_block++) {
+ if (relative_block == map.m_len) {
+ /* needed? */
+ map.m_flags &= ~EXT4_MAP_MAPPED;
+ break;
+ } else if (page_block == blocks_per_page)
+ break;
+ blocks[page_block] = map.m_pblk+relative_block;
+ page_block++;
+ block_in_file++;
+ }
+ }
+ if (first_hole != blocks_per_page) {
+ zero_user_segment(page, first_hole << blkbits,
+ PAGE_CACHE_SIZE);
+ if (first_hole == 0) {
+ SetPageUptodate(page);
+ unlock_page(page);
+ goto next_page;
+ }
+ } else if (fully_mapped) {
+ SetPageMappedToDisk(page);
+ }
+ if (fully_mapped && blocks_per_page == 1 &&
+ !PageUptodate(page) && cleancache_get_page(page) == 0) {
+ SetPageUptodate(page);
+ goto confused;
+ }
+
+ /*
+ * This page will go to BIO. Do we need to send this
+ * BIO off first?
+ */
+ if (bio && (last_block_in_bio != blocks[0] - 1)) {
+ submit_and_realloc:
+ submit_bio(READ, bio);
+ bio = NULL;
+ }
+ if (bio == NULL) {
+ bio = bio_alloc(GFP_KERNEL,
+ min_t(int, nr_pages, bio_get_nr_vecs(bdev)));
+ if (!bio)
+ goto set_error_page;
+ bio->bi_bdev = bdev;
+ bio->bi_sector = blocks[0] << (blkbits - 9);
+ bio->bi_end_io = mpage_end_io;
+ }
+
+ length = first_hole << blkbits;
+ if (bio_add_page(bio, page, length, 0) < length)
+ goto submit_and_realloc;
+
+ if (((map.m_flags & EXT4_MAP_BOUNDARY) &&
+ (relative_block == map.m_len)) ||
+ (first_hole != blocks_per_page)) {
+ submit_bio(READ, bio);
+ bio = NULL;
+ } else
+ last_block_in_bio = blocks[blocks_per_page - 1];
+ goto next_page;
+ confused:
+ if (bio) {
+ submit_bio(READ, bio);
+ bio = NULL;
+ }
+ if (!PageUptodate(page))
+ block_read_full_page(page, ext4_get_block);
+ else
+ unlock_page(page);
+ next_page:
+ if (pages)
+ page_cache_release(page);
+ }
+ BUG_ON(pages && !list_empty(pages));
+ if (bio)
+ submit_bio(READ, bio);
+ return 0;
+}
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 04f7fc1a523..26ee4e1a4ed 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -1911,7 +1911,8 @@ retry:
n_desc_blocks = o_desc_blocks +
le16_to_cpu(es->s_reserved_gdt_blocks);
n_group = n_desc_blocks * EXT4_DESC_PER_BLOCK(sb);
- n_blocks_count = n_group * EXT4_BLOCKS_PER_GROUP(sb);
+ n_blocks_count = (ext4_fsblk_t)n_group *
+ EXT4_BLOCKS_PER_GROUP(sb);
n_group--; /* set to last group number */
}
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index ad3dd732495..46e73254b52 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -305,6 +305,8 @@ static void __save_error_info(struct super_block *sb, const char *func,
struct ext4_super_block *es = EXT4_SB(sb)->s_es;
EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS;
+ if (bdev_read_only(sb->s_bdev))
+ return;
es->s_state |= cpu_to_le16(EXT4_ERROR_FS);
es->s_last_error_time = cpu_to_le32(get_seconds());
strncpy(es->s_last_error_func, func, sizeof(es->s_last_error_func));
@@ -3552,7 +3554,15 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
if (blocksize < EXT4_MIN_BLOCK_SIZE ||
blocksize > EXT4_MAX_BLOCK_SIZE) {
ext4_msg(sb, KERN_ERR,
- "Unsupported filesystem blocksize %d", blocksize);
+ "Unsupported filesystem blocksize %d (%d log_block_size)",
+ blocksize, le32_to_cpu(es->s_log_block_size));
+ goto failed_mount;
+ }
+ if (le32_to_cpu(es->s_log_block_size) >
+ (EXT4_MAX_BLOCK_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) {
+ ext4_msg(sb, KERN_ERR,
+ "Invalid log block size: %u",
+ le32_to_cpu(es->s_log_block_size));
goto failed_mount;
}
@@ -3671,6 +3681,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
"block size (%d)", clustersize, blocksize);
goto failed_mount;
}
+ if (le32_to_cpu(es->s_log_cluster_size) >
+ (EXT4_MAX_CLUSTER_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) {
+ ext4_msg(sb, KERN_ERR,
+ "Invalid log cluster size: %u",
+ le32_to_cpu(es->s_log_cluster_size));
+ goto failed_mount;
+ }
sbi->s_cluster_bits = le32_to_cpu(es->s_log_cluster_size) -
le32_to_cpu(es->s_log_block_size);
sbi->s_clusters_per_group =
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index 92850bab451..dde00d1e299 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -1266,11 +1266,13 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
int s_min_extra_isize = le16_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize);
down_write(&EXT4_I(inode)->xattr_sem);
+ /*
+ * Set EXT4_STATE_NO_EXPAND to avoid recursion when marking inode dirty
+ */
+ ext4_set_inode_state(inode, EXT4_STATE_NO_EXPAND);
retry:
- if (EXT4_I(inode)->i_extra_isize >= new_extra_isize) {
- up_write(&EXT4_I(inode)->xattr_sem);
- return 0;
- }
+ if (EXT4_I(inode)->i_extra_isize >= new_extra_isize)
+ goto out;
header = IHDR(inode, raw_inode);
entry = IFIRST(header);
@@ -1295,8 +1297,7 @@ retry:
(void *)header, total_ino,
inode->i_sb->s_blocksize);
EXT4_I(inode)->i_extra_isize = new_extra_isize;
- error = 0;
- goto cleanup;
+ goto out;
}
/*
@@ -1457,6 +1458,8 @@ retry:
kfree(bs);
}
brelse(bh);
+out:
+ ext4_clear_inode_state(inode, EXT4_STATE_NO_EXPAND);
up_write(&EXT4_I(inode)->xattr_sem);
return 0;
@@ -1468,6 +1471,10 @@ cleanup:
kfree(is);
kfree(bs);
brelse(bh);
+ /*
+ * We deliberately leave EXT4_STATE_NO_EXPAND set here since inode
+ * size expansion failed.
+ */
up_write(&EXT4_I(inode)->xattr_sem);
return error;
}
diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h
index c767dbdd7fc..7037e910944 100644
--- a/fs/ext4/xattr.h
+++ b/fs/ext4/xattr.h
@@ -23,6 +23,7 @@
#define EXT4_XATTR_INDEX_SECURITY 6
#define EXT4_XATTR_INDEX_SYSTEM 7
#define EXT4_XATTR_INDEX_RICHACL 8
+#define EXT4_XATTR_INDEX_ENCRYPTION 9
struct ext4_xattr_header {
__le32 h_magic; /* magic number for identification */
@@ -100,6 +101,8 @@ extern const struct xattr_handler ext4_xattr_acl_access_handler;
extern const struct xattr_handler ext4_xattr_acl_default_handler;
extern const struct xattr_handler ext4_xattr_security_handler;
+#define EXT4_XATTR_NAME_ENCRYPTION_CONTEXT "c"
+
extern ssize_t ext4_listxattr(struct dentry *, char *, size_t);
extern int ext4_xattr_get(struct inode *, int, const char *, void *, size_t);
diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c
index 9ae61eca788..5b952c05903 100644
--- a/fs/f2fs/acl.c
+++ b/fs/f2fs/acl.c
@@ -228,10 +228,12 @@ static int f2fs_set_acl(struct inode *inode, int type,
case ACL_TYPE_ACCESS:
name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS;
if (acl) {
- error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
- if (error)
+ error = posix_acl_equiv_mode(acl, &inode->i_mode);
+ if (error < 0)
return error;
set_acl_inode(fi, inode->i_mode);
+ if (error == 0)
+ acl = NULL;
}
break;
diff --git a/fs/f2fs~a6f9f264ace7... fs: use motorola_kernel b/fs/f2fs~a6f9f264ace7... fs: use motorola_kernel
new file mode 120000
index 00000000000..e3e532097e4
--- /dev/null
+++ b/fs/f2fs~a6f9f264ace7... fs: use motorola_kernel
@@ -0,0 +1 @@
+../../motorola/kernel/fs/f2fs/ \ No newline at end of file
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 2ca61f1daf3..908f87e88c2 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -1170,7 +1170,7 @@ void __mark_inode_dirty(struct inode *inode, int flags)
if ((inode->i_state & flags) == flags)
return;
- if (unlikely(block_dump))
+ if (unlikely(block_dump > 1))
block_dump___mark_inode_dirty(inode);
spin_lock(&inode->i_lock);
diff --git a/fs/fscache/object-list.c b/fs/fscache/object-list.c
index f27c89d1788..e7cf8c5f267 100644
--- a/fs/fscache/object-list.c
+++ b/fs/fscache/object-list.c
@@ -338,6 +338,13 @@ static void fscache_objlist_config(struct fscache_objlist_data *data)
rcu_read_lock();
confkey = key->payload.data;
+ if (!confkey) {
+ /* key was revoked */
+ rcu_read_unlock();
+ key_put(key);
+ goto no_config;
+ }
+
buf = confkey->data;
for (len = confkey->datalen - 1; len >= 0; len--) {
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 28eb26b9291..33841db8b4c 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -60,7 +60,7 @@ struct fuse_file *fuse_file_alloc(struct fuse_conn *fc)
{
struct fuse_file *ff;
- ff = kmalloc(sizeof(struct fuse_file), GFP_KERNEL);
+ ff = kzalloc(sizeof(struct fuse_file), GFP_KERNEL);
if (unlikely(!ff))
return NULL;
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index f1162e1dfe4..a7bc3582ef0 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -941,7 +941,7 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req)
arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC |
FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES | FUSE_DONT_MASK |
FUSE_SPLICE_WRITE | FUSE_SPLICE_MOVE | FUSE_SPLICE_READ |
- FUSE_FLOCK_LOCKS | FUSE_HAS_IOCTL_DIR | FUSE_AUTO_INVAL_DATA |
+ FUSE_FLOCK_LOCKS | FUSE_IOCTL_DIR | FUSE_AUTO_INVAL_DATA |
FUSE_DO_READDIRPLUS | FUSE_READDIRPLUS_AUTO | FUSE_ASYNC_DIO |
FUSE_WRITEBACK_CACHE;
req->in.h.opcode = FUSE_INIT;
diff --git a/fs/generic_acl.c b/fs/generic_acl.c
index 21408084c3b..7855cfb938f 100644
--- a/fs/generic_acl.c
+++ b/fs/generic_acl.c
@@ -82,14 +82,20 @@ generic_acl_set(struct dentry *dentry, const char *name, const void *value,
return PTR_ERR(acl);
}
if (acl) {
+ struct posix_acl *old_acl;
+
error = posix_acl_valid(acl);
if (error)
goto failed;
switch (type) {
case ACL_TYPE_ACCESS:
- error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
- if (error)
+ old_acl = acl;
+ error = posix_acl_update_mode(inode, &inode->i_mode,
+ &acl);
+ if (error < 0)
goto failed;
+ if (!acl)
+ posix_acl_release(old_acl);
inode->i_ctime = CURRENT_TIME;
break;
case ACL_TYPE_DEFAULT:
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c
index db243db4403..d4b2bbd7cf4 100644
--- a/fs/gfs2/acl.c
+++ b/fs/gfs2/acl.c
@@ -267,10 +267,10 @@ static int gfs2_xattr_system_set(struct dentry *dentry, const char *name,
goto out_release;
if (type == ACL_TYPE_ACCESS) {
- umode_t mode = inode->i_mode;
+ umode_t mode;
struct posix_acl *old_acl = acl;
- error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+ error = posix_acl_update_mode(inode, &mode, &acl);
if (!acl)
posix_acl_release(old_acl);
if (error)
diff --git a/fs/inode.c b/fs/inode.c
index eb66712897d..6b164e9d84d 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1935,3 +1935,34 @@ void inode_dio_done(struct inode *inode)
wake_up_bit(&inode->i_state, __I_DIO_WAKEUP);
}
EXPORT_SYMBOL(inode_dio_done);
+
+/*
+ * inode_set_flags - atomically set some inode flags
+ *
+ * Note: the caller should be holding i_mutex, or else be sure that
+ * they have exclusive access to the inode structure (i.e., while the
+ * inode is being instantiated). The reason for the cmpxchg() loop
+ * --- which wouldn't be necessary if all code paths which modify
+ * i_flags actually followed this rule, is that there is at least one
+ * code path which doesn't today --- for example,
+ * __generic_file_aio_write() calls file_remove_suid() without holding
+ * i_mutex --- so we use cmpxchg() out of an abundance of caution.
+ *
+ * In the long run, i_mutex is overkill, and we should probably look
+ * at using the i_lock spinlock to protect i_flags, and then make sure
+ * it is so documented in include/linux/fs.h and that all code follows
+ * the locking convention!!
+ */
+void inode_set_flags(struct inode *inode, unsigned int flags,
+ unsigned int mask)
+{
+ unsigned int old_flags, new_flags;
+
+ WARN_ON_ONCE(flags & ~mask);
+ do {
+ old_flags = ACCESS_ONCE(inode->i_flags);
+ new_flags = (old_flags & ~mask) | flags;
+ } while (unlikely(cmpxchg(&inode->i_flags, old_flags,
+ new_flags) != old_flags));
+}
+EXPORT_SYMBOL(inode_set_flags);
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
index 02bdfe007aa..7adb97da7b2 100644
--- a/fs/jfs/xattr.c
+++ b/fs/jfs/xattr.c
@@ -694,9 +694,10 @@ static int can_set_system_xattr(struct inode *inode, const char *name,
}
if (acl) {
struct posix_acl *old_acl = acl;
+
rc = posix_acl_update_mode(inode, &inode->i_mode, &acl);
posix_acl_release(old_acl);
- if (rc) {
+ if (rc < 0) {
printk(KERN_ERR
"posix_acl_update_mode returned %d\n",
rc);
diff --git a/fs/namespace.c b/fs/namespace.c
index a8af5666a9e..d7e655a82f2 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -188,6 +188,7 @@ static struct mount *alloc_vfsmnt(const char *name)
mnt->mnt_count = 1;
mnt->mnt_writers = 0;
#endif
+ mnt->mnt.data = NULL;
INIT_LIST_HEAD(&mnt->mnt_hash);
INIT_LIST_HEAD(&mnt->mnt_child);
@@ -785,7 +786,6 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
if (!mnt)
return ERR_PTR(-ENOMEM);
- mnt->mnt.data = NULL;
if (type->alloc_mnt_data) {
mnt->mnt.data = type->alloc_mnt_data();
if (!mnt->mnt.data) {
@@ -799,7 +799,6 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
root = mount_fs(type, flags, name, &mnt->mnt, data);
if (IS_ERR(root)) {
- kfree(mnt->mnt.data);
free_vfsmnt(mnt);
return ERR_CAST(root);
}
@@ -897,7 +896,6 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root,
return mnt;
out_free:
- kfree(mnt->mnt.data);
free_vfsmnt(mnt);
return ERR_PTR(err);
}
@@ -2365,9 +2363,9 @@ long do_mount(const char *dev_name, const char *dir_name,
if (retval)
goto dput_out;
- /* Default to noatime/nodiratime unless overriden */
- if (!(flags & MS_RELATIME))
- mnt_flags |= MNT_NOATIME;
+ /* Default to relatime unless overriden */
+ if (!(flags & MS_NOATIME))
+ mnt_flags |= MNT_RELATIME;
/* Separate the per-mountpoint flags */
if (flags & MS_NOSUID)
@@ -2376,9 +2374,9 @@ long do_mount(const char *dev_name, const char *dir_name,
mnt_flags |= MNT_NODEV;
if (flags & MS_NOEXEC)
mnt_flags |= MNT_NOEXEC;
- //if (flags & MS_NOATIME)
+ if (flags & MS_NOATIME)
mnt_flags |= MNT_NOATIME;
- //if (flags & MS_NODIRATIME)
+ if (flags & MS_NODIRATIME)
mnt_flags |= MNT_NODIRATIME;
if (flags & MS_STRICTATIME)
mnt_flags &= ~(MNT_RELATIME | MNT_NOATIME);
diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c
index 2fe643160cf..713f87d3f1e 100644
--- a/fs/ocfs2/acl.c
+++ b/fs/ocfs2/acl.c
@@ -274,14 +274,20 @@ static int ocfs2_set_acl(handle_t *handle,
case ACL_TYPE_ACCESS:
name_index = OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS;
if (acl) {
- umode_t mode = inode->i_mode;
+ umode_t mode;
+
ret = posix_acl_update_mode(inode, &mode, &acl);
if (ret)
return ret;
- ret = ocfs2_acl_set_mode(inode, di_bh,
- handle, mode);
- if (ret)
- return ret;
+ else {
+ if (ret == 0)
+ acl = NULL;
+
+ ret = ocfs2_acl_set_mode(inode, di_bh,
+ handle, mode);
+ if (ret)
+ return ret;
+ }
}
break;
case ACL_TYPE_DEFAULT:
diff --git a/fs/posix_acl.c b/fs/posix_acl.c
index 35cc1f40b82..2bc32c0b30c 100644
--- a/fs/posix_acl.c
+++ b/fs/posix_acl.c
@@ -341,37 +341,6 @@ static int posix_acl_create_masq(struct posix_acl *acl, umode_t *mode_p)
return not_equiv;
}
-/**
- * posix_acl_update_mode - update mode in set_acl
- *
- * Update the file mode when setting an ACL: compute the new file permission
- * bits based on the ACL. In addition, if the ACL is equivalent to the new
- * file mode, set *acl to NULL to indicate that no ACL should be set.
- *
- * As with chmod, clear the setgit bit if the caller is not in the owning group
- * or capable of CAP_FSETID (see inode_change_ok).
- *
- * Called from set_acl inode operations.
- */
-int posix_acl_update_mode(struct inode *inode, umode_t *mode_p,
- struct posix_acl **acl)
-{
- umode_t mode = inode->i_mode;
- int error;
-
- error = posix_acl_equiv_mode(*acl, &mode);
- if (error < 0)
- return error;
- if (error == 0)
- *acl = NULL;
- if (!in_group_p(inode->i_gid) &&
- !capable_wrt_inode_uidgid(inode, CAP_FSETID))
- mode &= ~S_ISGID;
- *mode_p = mode;
- return 0;
-}
-EXPORT_SYMBOL(posix_acl_update_mode);
-
/*
* Modify the ACL for the chmod syscall.
*/
@@ -455,3 +424,34 @@ posix_acl_chmod(struct posix_acl **acl, gfp_t gfp, umode_t mode)
return err;
}
EXPORT_SYMBOL(posix_acl_chmod);
+
+/**
+ * posix_acl_update_mode - update mode in set_acl
+ *
+ * Update the file mode when setting an ACL: compute the new file permission
+ * bits based on the ACL. In addition, if the ACL is equivalent to the new
+ * file mode, set *acl to NULL to indicate that no ACL should be set.
+ *
+ * As with chmod, clear the setgit bit if the caller is not in the owning group
+ * or capable of CAP_FSETID (see inode_change_ok).
+ *
+ * Called from set_acl inode operations.
+ */
+int posix_acl_update_mode(struct inode *inode, umode_t *mode_p,
+ struct posix_acl **acl)
+{
+ umode_t mode = inode->i_mode;
+ int error;
+
+ error = posix_acl_equiv_mode(*acl, &mode);
+ if (error < 0)
+ return error;
+ if (error == 0)
+ *acl = NULL;
+ if (!in_group_p(inode->i_gid) &&
+ !capable_wrt_inode_uidgid(inode, CAP_FSETID))
+ mode &= ~S_ISGID;
+ *mode_p = mode;
+ return 0;
+}
+EXPORT_SYMBOL(posix_acl_update_mode);
diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c
index 5fd5d6a899b..a48f623d9a3 100644
--- a/fs/pstore/ram_core.c
+++ b/fs/pstore/ram_core.c
@@ -58,7 +58,7 @@ static size_t buffer_start_add(struct persistent_ram_zone *prz, size_t a)
old = atomic_read(&prz->buffer->start);
new = old + a;
- while (unlikely(new > prz->buffer_size))
+ while (unlikely(new >= prz->buffer_size))
new -= prz->buffer_size;
atomic_set(&prz->buffer->start, new);
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c
index 2d73589f37d..df5ad557481 100644
--- a/fs/reiserfs/xattr_acl.c
+++ b/fs/reiserfs/xattr_acl.c
@@ -286,7 +286,8 @@ reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode,
case ACL_TYPE_ACCESS:
name = POSIX_ACL_XATTR_ACCESS;
if (acl) {
- error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+ error = posix_acl_update_mode(inode,
+ &inode->i_mode, &acl);
if (error)
return error;
}
diff --git a/fs/sdcardfs/derived_perm.c b/fs/sdcardfs/derived_perm.c
index 64f188f8488..75beeff149f 100755
--- a/fs/sdcardfs/derived_perm.c
+++ b/fs/sdcardfs/derived_perm.c
@@ -175,6 +175,9 @@ void fixup_lower_ownership(struct dentry *dentry, const char *name)
gid_t gid = sbi->options.fs_low_gid;
struct iattr newattrs;
+ if (!sbi->options.gid_derivation)
+ return;
+
info = SDCARDFS_I(dentry->d_inode);
info_d = info->data;
perm = info_d->perm;
diff --git a/fs/sdcardfs/file.c b/fs/sdcardfs/file.c
index a1f12e27f3c..6d6be71c256 100755
--- a/fs/sdcardfs/file.c
+++ b/fs/sdcardfs/file.c
@@ -334,11 +334,6 @@ static int sdcardfs_fasync(int fd, struct file *file, int flag)
return err;
}
-static struct file *sdcardfs_get_lower_file(struct file *f)
-{
- return sdcardfs_lower_file(f);
-}
-
/*
* Sdcardfs cannot use generic_file_llseek as ->llseek, because it would
* only set the offset of the upper file. So we have to implement our
@@ -362,6 +357,11 @@ out:
}
+static struct file *sdcardfs_get_lower_file(struct file *f)
+{
+ return sdcardfs_lower_file(f);
+}
+
const struct file_operations sdcardfs_main_fops = {
.llseek = generic_file_llseek,
.read = sdcardfs_read,
diff --git a/fs/sdcardfs/inode.c b/fs/sdcardfs/inode.c
index 030210ac8e1..c7fe86f89ca 100755
--- a/fs/sdcardfs/inode.c
+++ b/fs/sdcardfs/inode.c
@@ -34,10 +34,14 @@ const struct cred *override_fsids(struct sdcardfs_sb_info *sbi,
if (!cred)
return NULL;
- if (data->under_obb)
- uid = AID_MEDIA_OBB;
- else
- uid = multiuser_get_uid(data->userid, sbi->options.fs_low_uid);
+ if (sbi->options.gid_derivation) {
+ if (data->under_obb)
+ uid = AID_MEDIA_OBB;
+ else
+ uid = multiuser_get_uid(data->userid, sbi->options.fs_low_uid);
+ } else {
+ uid = sbi->options.fs_low_uid;
+ }
cred->fsuid = uid;
cred->fsgid = sbi->options.fs_low_gid;
diff --git a/fs/sdcardfs/main.c b/fs/sdcardfs/main.c
index 6c6904e8618..909193e1687 100755
--- a/fs/sdcardfs/main.c
+++ b/fs/sdcardfs/main.c
@@ -32,6 +32,7 @@ enum {
Opt_multiuser,
Opt_userid,
Opt_reserved_mb,
+ Opt_gid_derivation,
Opt_err,
};
@@ -43,6 +44,7 @@ static const match_table_t sdcardfs_tokens = {
{Opt_mask, "mask=%u"},
{Opt_userid, "userid=%d"},
{Opt_multiuser, "multiuser"},
+ {Opt_gid_derivation, "derive_gid"},
{Opt_reserved_mb, "reserved_mb=%u"},
{Opt_err, NULL}
};
@@ -64,6 +66,8 @@ static int parse_options(struct super_block *sb, char *options, int silent,
vfsopts->gid = 0;
/* by default, 0MB is reserved */
opts->reserved_mb = 0;
+ /* by default, gid derivation is off */
+ opts->gid_derivation = false;
*debug = 0;
@@ -115,6 +119,9 @@ static int parse_options(struct super_block *sb, char *options, int silent,
return 0;
opts->reserved_mb = option;
break;
+ case Opt_gid_derivation:
+ opts->gid_derivation = true;
+ break;
/* unknown option */
default:
if (!silent)
diff --git a/fs/sdcardfs/sdcardfs.h b/fs/sdcardfs/sdcardfs.h
index 63c3bd32910..f3c283759cb 100755
--- a/fs/sdcardfs/sdcardfs.h
+++ b/fs/sdcardfs/sdcardfs.h
@@ -218,6 +218,7 @@ struct sdcardfs_mount_options {
gid_t fs_low_gid;
userid_t fs_user_id;
bool multiuser;
+ bool gid_derivation;
unsigned int reserved_mb;
};
diff --git a/fs/sdcardfs/super.c b/fs/sdcardfs/super.c
index 7f4539b4b24..b89947d878e 100755
--- a/fs/sdcardfs/super.c
+++ b/fs/sdcardfs/super.c
@@ -302,6 +302,8 @@ static int sdcardfs_show_options(struct vfsmount *mnt, struct seq_file *m,
seq_printf(m, ",mask=%u", vfsopts->mask);
if (opts->fs_user_id)
seq_printf(m, ",userid=%u", opts->fs_user_id);
+ if (opts->gid_derivation)
+ seq_puts(m, ",derive_gid");
if (opts->reserved_mb != 0)
seq_printf(m, ",reserved=%uMB", opts->reserved_mb);
diff --git a/fs/super.c b/fs/super.c
index 0eec81d77bb..55a171fe9d7 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -1346,8 +1346,8 @@ int freeze_super(struct super_block *sb)
}
}
/*
- * This is just for debugging purposes so that fs can warn if it
- * sees write activity when frozen is set to SB_FREEZE_COMPLETE.
+ * For debugging purposes so that fs can warn if it sees write activity
+ * when frozen is set to SB_FREEZE_COMPLETE, and for thaw_super().
*/
sb->s_writers.frozen = SB_FREEZE_COMPLETE;
up_write(&sb->s_umount);
@@ -1366,7 +1366,7 @@ int thaw_super(struct super_block *sb)
int error;
down_write(&sb->s_umount);
- if (sb->s_writers.frozen == SB_UNFROZEN) {
+ if (sb->s_writers.frozen != SB_FREEZE_COMPLETE) {
up_write(&sb->s_umount);
return -EINVAL;
}
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 48de53e8ebf..b0f645e14b8 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -350,8 +350,7 @@ static unsigned int vfs_dent_type(uint8_t type)
*/
static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
{
- int err = 0;
- int over = 0;
+ int err, over = 0;
loff_t pos = file->f_pos;
struct qstr nm;
union ubifs_key key;
@@ -473,21 +472,15 @@ out:
kfree(file->private_data);
file->private_data = NULL;
- if (err != -ENOENT)
+ if (err != -ENOENT) {
ubifs_err("cannot find next direntry, error %d", c->vi.ubi_num,
err);
- else
- /*
- * -ENOENT is a non-fatal error in this context, the TNC uses
- * it to indicate that the cursor moved past the current directory
- * and readdir() has to stop.
- */
- err = 0;
-
+ return err;
+ }
/* 2 is a special value indicating that there are no more direntries */
file->f_pos = 2;
- return err;
+ return 0;
}
static loff_t ubifs_dir_llseek(struct file *file, loff_t offset, int whence)
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 5c1120a5fa4..76e54779b7a 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -1237,8 +1237,8 @@ int udf_setsize(struct inode *inode, loff_t newsize)
return err;
}
set_size:
- truncate_setsize(inode, newsize);
up_write(&iinfo->i_data_sem);
+ truncate_setsize(inode, newsize);
} else {
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
down_write(&iinfo->i_data_sem);
@@ -1255,9 +1255,9 @@ set_size:
udf_get_block);
if (err)
return err;
+ truncate_setsize(inode, newsize);
down_write(&iinfo->i_data_sem);
udf_clear_extent_cache(inode);
- truncate_setsize(inode, newsize);
udf_truncate_extents(inode);
up_write(&iinfo->i_data_sem);
}
@@ -1495,15 +1495,19 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
iinfo->i_checkpoint = le32_to_cpu(efe->checkpoint);
}
- /*
- * Sanity check length of allocation descriptors and extended attrs to
- * avoid integer overflows
- */
- if (iinfo->i_lenEAttr > inode->i_sb->s_blocksize || iinfo->i_lenAlloc > inode->i_sb->s_blocksize)
- return;
- /* Now do exact checks */
- if (udf_file_entry_alloc_offset(inode) + iinfo->i_lenAlloc > inode->i_sb->s_blocksize)
- return;
+ /* Sanity checks for files in ICB so that we don't get confused later */
+ if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
+ /*
+ * For file in ICB data is stored in allocation descriptor
+ * so sizes should match
+ */
+ if (iinfo->i_lenAlloc != inode->i_size)
+ return;
+ /* File in ICB has to fit in there... */
+ if (inode->i_size > inode->i_sb->s_blocksize -
+ udf_file_entry_alloc_offset(inode))
+ return;
+ }
switch (fe->icbTag.fileType) {
case ICBTAG_FILE_TYPE_DIRECTORY:
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
index eaa2a373551..0c59d960efe 100644
--- a/fs/xfs/xfs_acl.c
+++ b/fs/xfs/xfs_acl.c
@@ -388,13 +388,15 @@ xfs_xattr_acl_set(struct dentry *dentry, const char *name,
goto out_release;
if (type == ACL_TYPE_ACCESS) {
- umode_t mode = inode->i_mode;
+ umode_t mode;
struct posix_acl *old_acl = acl;
+
error = posix_acl_update_mode(inode, &mode, &acl);
if (!acl)
posix_acl_release(old_acl);
if (error)
goto out_release;
+
error = xfs_set_mode(inode, mode);
if (error)
goto out_release;
diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h
index d17784ea37f..344c1956581 100644
--- a/include/asm-generic/percpu.h
+++ b/include/asm-generic/percpu.h
@@ -87,6 +87,9 @@ extern void setup_per_cpu_areas(void);
#endif /* SMP */
+/* 3.18 backport */
+#define raw_cpu_ptr(ptr) __this_cpu_ptr(ptr)
+
#ifndef PER_CPU_BASE_SECTION
#ifdef CONFIG_SMP
#define PER_CPU_BASE_SECTION ".data..percpu"
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index e9b04cd8032..6579f0e4548 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -475,7 +475,7 @@ struct request_queue {
#define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \
(1 << QUEUE_FLAG_STACKABLE) | \
(1 << QUEUE_FLAG_SAME_COMP) | \
- (0 << QUEUE_FLAG_ADD_RANDOM))
+ (1 << QUEUE_FLAG_ADD_RANDOM))
static inline void queue_lockdep_assert_held(struct request_queue *q)
{
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index ca31306f7b5..8236ef859a9 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -297,6 +297,18 @@ sb_bread(struct super_block *sb, sector_t block)
return __bread(sb->s_bdev, block, sb->s_blocksize);
}
+static inline struct buffer_head *
+sb_bread_unmovable(struct super_block *sb, sector_t block)
+{
+ return sb_bread(sb, block);
+}
+
+static inline struct buffer_head *getblk_unmovable(struct block_device *bdev,
+ sector_t block, unsigned size)
+{
+ return __getblk(bdev, block, size);
+}
+
static inline void
sb_breadahead(struct super_block *sb, sector_t block)
{
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index 953cd12175c..cdf13ca7cac 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -66,6 +66,7 @@
#define __deprecated __attribute__((deprecated))
#define __packed __attribute__((packed))
#define __weak __attribute__((weak))
+#define __alias(symbol) __attribute__((alias(#symbol)))
/*
* it doesn't make sense on ARM (currently the only user of __naked) to trace
@@ -100,116 +101,10 @@
#define __maybe_unused __attribute__((unused))
#define __always_unused __attribute__((unused))
-/* gcc version specific checks */
-
-#if GCC_VERSION < 30200
-# error Sorry, your compiler is too old - please upgrade it.
-#endif
-
-#if GCC_VERSION < 30300
-# define __used __attribute__((__unused__))
-#else
-# define __used __attribute__((__used__))
-#endif
-
-#ifdef CONFIG_GCOV_KERNEL
-# if GCC_VERSION < 30400
-# error "GCOV profiling support for gcc versions below 3.4 not included"
-# endif /* __GNUC_MINOR__ */
-#endif /* CONFIG_GCOV_KERNEL */
-
-#if GCC_VERSION >= 30400
-#define __must_check __attribute__((warn_unused_result))
-#endif
-
-#if GCC_VERSION >= 40000
-
-/* GCC 4.1.[01] miscompiles __weak */
-#ifdef __KERNEL__
-# if GCC_VERSION >= 40100 && GCC_VERSION <= 40101
-# error Your version of gcc miscompiles the __weak directive
-# endif
-#endif
-
-#define __used __attribute__((__used__))
-#define __compiler_offsetof(a, b) \
- __builtin_offsetof(a, b)
-
-#if GCC_VERSION >= 40100 && GCC_VERSION < 40600
-# define __compiletime_object_size(obj) __builtin_object_size(obj, 0)
-#endif
-
-#if GCC_VERSION >= 40300
-/* Mark functions as cold. gcc will assume any path leading to a call
- * to them will be unlikely. This means a lot of manual unlikely()s
- * are unnecessary now for any paths leading to the usual suspects
- * like BUG(), printk(), panic() etc. [but let's keep them for now for
- * older compilers]
- *
- * Early snapshots of gcc 4.3 don't support this and we can't detect this
- * in the preprocessor, but we can live with this because they're unreleased.
- * Maketime probing would be overkill here.
- *
- * gcc also has a __attribute__((__hot__)) to move hot functions into
- * a special section, but I don't see any sense in this right now in
- * the kernel context
- */
-#define __cold __attribute__((__cold__))
-
-#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
-
-#ifndef __CHECKER__
-# define __compiletime_warning(message) __attribute__((warning(message)))
-# define __compiletime_error(message) __attribute__((error(message)))
-#endif /* __CHECKER__ */
-#endif /* GCC_VERSION >= 40300 */
-
-#if GCC_VERSION >= 40500
-/*
- * Mark a position in code as unreachable. This can be used to
- * suppress control flow warnings after asm blocks that transfer
- * control elsewhere.
- *
- * Early snapshots of gcc 4.5 don't support this and we can't detect
- * this in the preprocessor, but we can live with this because they're
- * unreleased. Really, we need to have autoconf for the kernel.
- */
-#define unreachable() __builtin_unreachable()
-
-/* Mark a function definition as prohibited from being cloned. */
-#define __noclone __attribute__((__noclone__, __optimize__("no-tracer")))
-
-#endif /* GCC_VERSION >= 40500 */
-
-#if GCC_VERSION >= 40600
-/*
- * Tell the optimizer that something else uses this function or variable.
- */
-#define __visible __attribute__((externally_visible))
-#endif
-
-/*
- * GCC 'asm goto' miscompiles certain code sequences:
- *
- * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
- *
- * Work it around via a compiler barrier quirk suggested by Jakub Jelinek.
- *
- * (asm goto is automatically volatile - the naming reflects this.)
- */
-#define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0)
-
-#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP
-#if GCC_VERSION >= 40400
-#define __HAVE_BUILTIN_BSWAP32__
-#define __HAVE_BUILTIN_BSWAP64__
-#endif
-#if GCC_VERSION >= 40800 || (defined(__powerpc__) && GCC_VERSION >= 40600)
-#define __HAVE_BUILTIN_BSWAP16__
-#endif
-#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */
-
-#endif /* gcc version >= 40000 specific checks */
+#define __gcc_header(x) #x
+#define _gcc_header(x) __gcc_header(linux/compiler-gcc##x.h)
+#define gcc_header(x) _gcc_header(x)
+#include gcc_header(__GNUC__)
#if !defined(__noclone)
#define __noclone /* not needed */
diff --git a/include/linux/compiler-gcc3.h b/include/linux/compiler-gcc3.h
new file mode 100644
index 00000000000..7d89febe4d7
--- /dev/null
+++ b/include/linux/compiler-gcc3.h
@@ -0,0 +1,23 @@
+#ifndef __LINUX_COMPILER_H
+#error "Please don't include <linux/compiler-gcc3.h> directly, include <linux/compiler.h> instead."
+#endif
+
+#if GCC_VERSION < 30200
+# error Sorry, your compiler is too old - please upgrade it.
+#endif
+
+#if GCC_VERSION >= 30300
+# define __used __attribute__((__used__))
+#else
+# define __used __attribute__((__unused__))
+#endif
+
+#if GCC_VERSION >= 30400
+#define __must_check __attribute__((warn_unused_result))
+#endif
+
+#ifdef CONFIG_GCOV_KERNEL
+# if GCC_VERSION < 30400
+# error "GCOV profiling support for gcc versions below 3.4 not included"
+# endif /* __GNUC_MINOR__ */
+#endif /* CONFIG_GCOV_KERNEL */
diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h
new file mode 100644
index 00000000000..769e1986463
--- /dev/null
+++ b/include/linux/compiler-gcc4.h
@@ -0,0 +1,91 @@
+#ifndef __LINUX_COMPILER_H
+#error "Please don't include <linux/compiler-gcc4.h> directly, include <linux/compiler.h> instead."
+#endif
+
+/* GCC 4.1.[01] miscompiles __weak */
+#ifdef __KERNEL__
+# if GCC_VERSION >= 40100 && GCC_VERSION <= 40101
+# error Your version of gcc miscompiles the __weak directive
+# endif
+#endif
+
+#define __used __attribute__((__used__))
+#define __must_check __attribute__((warn_unused_result))
+#define __compiler_offsetof(a,b) __builtin_offsetof(a,b)
+
+#if GCC_VERSION >= 40100 && GCC_VERSION < 40600
+# define __compiletime_object_size(obj) __builtin_object_size(obj, 0)
+#endif
+
+#if GCC_VERSION >= 40300
+/* Mark functions as cold. gcc will assume any path leading to a call
+ to them will be unlikely. This means a lot of manual unlikely()s
+ are unnecessary now for any paths leading to the usual suspects
+ like BUG(), printk(), panic() etc. [but let's keep them for now for
+ older compilers]
+
+ Early snapshots of gcc 4.3 don't support this and we can't detect this
+ in the preprocessor, but we can live with this because they're unreleased.
+ Maketime probing would be overkill here.
+
+ gcc also has a __attribute__((__hot__)) to move hot functions into
+ a special section, but I don't see any sense in this right now in
+ the kernel context */
+#define __cold __attribute__((__cold__))
+
+#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
+
+#ifndef __CHECKER__
+# define __compiletime_warning(message) __attribute__((warning(message)))
+# define __compiletime_error(message) __attribute__((error(message)))
+#endif /* __CHECKER__ */
+#endif /* GCC_VERSION >= 40300 */
+
+#if GCC_VERSION >= 40500
+/*
+ * Mark a position in code as unreachable. This can be used to
+ * suppress control flow warnings after asm blocks that transfer
+ * control elsewhere.
+ *
+ * Early snapshots of gcc 4.5 don't support this and we can't detect
+ * this in the preprocessor, but we can live with this because they're
+ * unreleased. Really, we need to have autoconf for the kernel.
+ */
+#define unreachable() __builtin_unreachable()
+
+/* Mark a function definition as prohibited from being cloned. */
+#define __noclone __attribute__((__noclone__))
+
+#endif /* GCC_VERSION >= 40500 */
+
+#if GCC_VERSION >= 40600
+/*
+ * Tell the optimizer that something else uses this function or variable.
+ */
+#define __visible __attribute__((externally_visible))
+#endif
+
+/*
+ * GCC 'asm goto' miscompiles certain code sequences:
+ *
+ * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
+ *
+ * Work it around via a compiler barrier quirk suggested by Jakub Jelinek.
+ *
+ * (asm goto is automatically volatile - the naming reflects this.)
+ */
+#define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0)
+
+#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP
+#if GCC_VERSION >= 40400
+#define __HAVE_BUILTIN_BSWAP32__
+#define __HAVE_BUILTIN_BSWAP64__
+#endif
+#if GCC_VERSION >= 40800 || (defined(__powerpc__) && GCC_VERSION >= 40600)
+#define __HAVE_BUILTIN_BSWAP16__
+#endif
+#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */
+
+#if GCC_VERSION >= 40902
+#define KASAN_ABI_VERSION 3
+#endif
diff --git a/include/linux/compiler-gcc5.h b/include/linux/compiler-gcc5.h
new file mode 100644
index 00000000000..efee493714e
--- /dev/null
+++ b/include/linux/compiler-gcc5.h
@@ -0,0 +1,67 @@
+#ifndef __LINUX_COMPILER_H
+#error "Please don't include <linux/compiler-gcc5.h> directly, include <linux/compiler.h> instead."
+#endif
+
+#define __used __attribute__((__used__))
+#define __must_check __attribute__((warn_unused_result))
+#define __compiler_offsetof(a, b) __builtin_offsetof(a, b)
+
+/* Mark functions as cold. gcc will assume any path leading to a call
+ to them will be unlikely. This means a lot of manual unlikely()s
+ are unnecessary now for any paths leading to the usual suspects
+ like BUG(), printk(), panic() etc. [but let's keep them for now for
+ older compilers]
+
+ Early snapshots of gcc 4.3 don't support this and we can't detect this
+ in the preprocessor, but we can live with this because they're unreleased.
+ Maketime probing would be overkill here.
+
+ gcc also has a __attribute__((__hot__)) to move hot functions into
+ a special section, but I don't see any sense in this right now in
+ the kernel context */
+#define __cold __attribute__((__cold__))
+
+#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
+
+#ifndef __CHECKER__
+# define __compiletime_warning(message) __attribute__((warning(message)))
+# define __compiletime_error(message) __attribute__((error(message)))
+#endif /* __CHECKER__ */
+
+/*
+ * Mark a position in code as unreachable. This can be used to
+ * suppress control flow warnings after asm blocks that transfer
+ * control elsewhere.
+ *
+ * Early snapshots of gcc 4.5 don't support this and we can't detect
+ * this in the preprocessor, but we can live with this because they're
+ * unreleased. Really, we need to have autoconf for the kernel.
+ */
+#define unreachable() __builtin_unreachable()
+
+/* Mark a function definition as prohibited from being cloned. */
+#define __noclone __attribute__((__noclone__))
+
+/*
+ * Tell the optimizer that something else uses this function or variable.
+ */
+#define __visible __attribute__((externally_visible))
+
+/*
+ * GCC 'asm goto' miscompiles certain code sequences:
+ *
+ * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
+ *
+ * Work it around via a compiler barrier quirk suggested by Jakub Jelinek.
+ *
+ * (asm goto is automatically volatile - the naming reflects this.)
+ */
+#define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0)
+
+#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP
+#define __HAVE_BUILTIN_BSWAP32__
+#define __HAVE_BUILTIN_BSWAP64__
+#define __HAVE_BUILTIN_BSWAP16__
+#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */
+
+#define KASAN_ABI_VERSION 4
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 6a37ab8073c..20d0d6d6136 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -164,7 +164,6 @@ static inline void disable_cpufreq(void) { }
#define CPUFREQ_RELATION_L 0 /* lowest frequency at or above target */
#define CPUFREQ_RELATION_H 1 /* highest frequency below or at target */
-#define CPUFREQ_RELATION_C 2 /* closest frequency to target */
struct freq_attr {
struct attribute attr;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index ca1bbbbf380..94cfd5254f9 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2517,6 +2517,9 @@ void inode_dio_wait(struct inode *inode);
void inode_dio_done(struct inode *inode);
struct inode *dio_bio_get_inode(struct bio *bio);
+extern void inode_set_flags(struct inode *inode, unsigned int flags,
+ unsigned int mask);
+
extern const struct file_operations generic_ro_fops;
#define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
@@ -2736,4 +2739,11 @@ static inline void inode_has_no_xattr(struct inode *inode)
inode->i_flags |= S_NOSEC;
}
+static inline bool dir_relax(struct inode *inode)
+{
+ mutex_unlock(&inode->i_mutex);
+ mutex_lock(&inode->i_mutex);
+ return !IS_DEADDIR(inode);
+}
+
#endif /* _LINUX_FS_H */
diff --git a/include/linux/i2c/i2c-msm-v2.h b/include/linux/i2c/i2c-msm-v2.h
index 34d2813ade4..02cae9b8759 100644
--- a/include/linux/i2c/i2c-msm-v2.h
+++ b/include/linux/i2c/i2c-msm-v2.h
@@ -26,12 +26,9 @@ enum msm_i2_debug_level {
MSM_DBG, /* Low level details. Use for debugging */
};
-#define CONFIG_I2C_MSM_DEBUG 0
#define i2c_msm_dbg(ctrl, dbg_level, fmt, ...) do {\
- if (CONFIG_I2C_MSM_DEBUG) {\
if (ctrl->dbgfs.dbg_lvl >= dbg_level)\
dev_info(ctrl->dev, pr_fmt(fmt), ##__VA_ARGS__);\
- }\
} while (0)
#define BIT_IS_SET(val, idx) ((val >> idx) & 0x1)
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 70c7437c41d..300fcc9c9da 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -554,7 +554,7 @@ do { \
#define do_trace_printk(fmt, args...) \
do { \
- static const char *trace_printk_fmt __used \
+ static const char *trace_printk_fmt \
__attribute__((section("__trace_printk_fmt"))) = \
__builtin_constant_p(fmt) ? fmt : NULL; \
\
@@ -601,7 +601,7 @@ extern int __trace_puts(unsigned long ip, const char *str, int size);
*/
#define trace_puts(str) ({ \
- static const char *trace_printk_fmt __used \
+ static const char *trace_printk_fmt \
__attribute__((section("__trace_printk_fmt"))) = \
__builtin_constant_p(str) ? str : NULL; \
\
@@ -621,7 +621,7 @@ extern void trace_dump_stack(int skip);
#define ftrace_vprintk(fmt, vargs) \
do { \
if (__builtin_constant_p(fmt)) { \
- static const char *trace_printk_fmt __used \
+ static const char *trace_printk_fmt \
__attribute__((section("__trace_printk_fmt"))) = \
__builtin_constant_p(fmt) ? fmt : NULL; \
\
diff --git a/include/linux/key.h b/include/linux/key.h
index b2752c35f42..994d52f00c1 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -171,6 +171,7 @@ struct key {
#define KEY_FLAG_NEGATIVE 5 /* set if key is negative */
#define KEY_FLAG_ROOT_CAN_CLEAR 6 /* set if key can be cleared by root without permission */
#define KEY_FLAG_INVALIDATED 7 /* set if key has been invalidated */
+#define KEY_FLAG_UID_KEYRING 11 /* set if key is a user or user session keyring */
/* the description string
* - this is used to match a key against search criteria
@@ -212,6 +213,7 @@ extern struct key *key_alloc(struct key_type *type,
#define KEY_ALLOC_IN_QUOTA 0x0000 /* add to quota, reject if would overrun */
#define KEY_ALLOC_QUOTA_OVERRUN 0x0001 /* add to quota, permit even if overrun */
#define KEY_ALLOC_NOT_IN_QUOTA 0x0002 /* not in quota */
+#define KEY_ALLOC_UID_KEYRING 0x0010 /* allocating a user or user session keyring */
extern void key_revoke(struct key *key);
extern void key_invalidate(struct key *key);
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 2629bdd95b3..e5eb3460de6 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1899,6 +1899,12 @@ static inline unsigned int debug_guardpage_minorder(void) { return 0; }
static inline bool page_is_guard(struct page *page) { return false; }
#endif /* CONFIG_DEBUG_PAGEALLOC */
+/* 3.18 backport */
+static inline void truncate_inode_pages_final(struct address_space *mapping)
+{
+ truncate_inode_pages(mapping, 0);
+}
+
#if MAX_NUMNODES > 1
void __init setup_nr_node_ids(void);
#else
diff --git a/include/linux/mmc/sdio_func.h b/include/linux/mmc/sdio_func.h
index dc680c4b50d..dc680c4b50d 100644..100755
--- a/include/linux/mmc/sdio_func.h
+++ b/include/linux/mmc/sdio_func.h
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 7a871e8e2a0..327a0190358 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -109,16 +109,9 @@ enum pageflags {
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
PG_compound_lock,
#endif
-#ifdef CONFIG_KSM_CHECK_PAGE
- PG_ksm_scan0, /* page has been scanned by even KSM cycle */
-#endif
PG_readahead, /* page in a readahead window */
__NR_PAGEFLAGS,
-#ifdef CONFIG_KSM_CHECK_PAGE
- /* page has been scanned by odd KSM cycle */
- PG_ksm_scan1 = PG_owner_priv_1,
-#endif
/* Filesystems */
PG_checked = PG_owner_priv_1,
@@ -218,10 +211,6 @@ PAGEFLAG(Reserved, reserved) __CLEARPAGEFLAG(Reserved, reserved)
PAGEFLAG(SwapBacked, swapbacked) __CLEARPAGEFLAG(SwapBacked, swapbacked)
__PAGEFLAG(SlobFree, slob_free)
-#ifdef CONFIG_KSM_CHECK_PAGE
-CLEARPAGEFLAG(KsmScan0, ksm_scan0) TESTSETFLAG(KsmScan0, ksm_scan0)
-CLEARPAGEFLAG(KsmScan1, ksm_scan1) TESTSETFLAG(KsmScan1, ksm_scan1)
-#endif
/*
* Private page markings that may be used by the filesystem that owns the page
@@ -329,13 +318,23 @@ CLEARPAGEFLAG(Uptodate, uptodate)
extern void cancel_dirty_page(struct page *page, unsigned int account_size);
int test_clear_page_writeback(struct page *page);
-int test_set_page_writeback(struct page *page);
+int __test_set_page_writeback(struct page *page, bool keep_write);
+
+#define test_set_page_writeback(page) \
+ __test_set_page_writeback(page, false)
+#define test_set_page_writeback_keepwrite(page) \
+ __test_set_page_writeback(page, true)
static inline void set_page_writeback(struct page *page)
{
test_set_page_writeback(page);
}
+static inline void set_page_writeback_keepwrite(struct page *page)
+{
+ test_set_page_writeback_keepwrite(page);
+}
+
#ifdef CONFIG_PAGEFLAGS_EXTENDED
/*
* System with lots of page flags available. This allows separate
diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h
index 2ae0bba45f1..94d2f4282a2 100644
--- a/include/linux/posix_acl.h
+++ b/include/linux/posix_acl.h
@@ -90,12 +90,14 @@ extern struct posix_acl *posix_acl_from_mode(umode_t, gfp_t);
extern int posix_acl_equiv_mode(const struct posix_acl *, umode_t *);
extern int posix_acl_create(struct posix_acl **, gfp_t, umode_t *);
extern int posix_acl_chmod(struct posix_acl **, gfp_t, umode_t);
-extern int posix_acl_update_mode(struct inode *, umode_t *, struct posix_acl **);
extern struct posix_acl *get_posix_acl(struct inode *, int);
extern int set_posix_acl(struct inode *, int, struct posix_acl *);
#ifdef CONFIG_FS_POSIX_ACL
+extern int posix_acl_update_mode(struct inode *, umode_t *,
+ struct posix_acl **);
+
static inline struct posix_acl **acl_by_type(struct inode *inode, int type)
{
switch (type) {
diff --git a/include/linux/preempt.h b/include/linux/preempt.h
index eaac52a8fe6..f5d4723cdb3 100644
--- a/include/linux/preempt.h
+++ b/include/linux/preempt.h
@@ -10,32 +10,19 @@
#include <linux/linkage.h>
#include <linux/list.h>
-static __always_inline int preempt_count(void)
-{
- return current_thread_info()->preempt_count;
-}
-
-static __always_inline int *preempt_count_ptr(void)
-{
- return &current_thread_info()->preempt_count;
-}
-
-static __always_inline void preempt_count_set(int pc)
-{
- *preempt_count_ptr() = pc;
-}
-
#if defined(CONFIG_DEBUG_PREEMPT) || defined(CONFIG_PREEMPT_TRACER)
extern void add_preempt_count(int val);
extern void sub_preempt_count(int val);
#else
-# define add_preempt_count(val) do { *preempt_count_ptr() += (val); } while (0)
-# define sub_preempt_count(val) do { *preempt_count_ptr() -= (val); } while (0)
+# define add_preempt_count(val) do { preempt_count() += (val); } while (0)
+# define sub_preempt_count(val) do { preempt_count() -= (val); } while (0)
#endif
#define inc_preempt_count() add_preempt_count(1)
#define dec_preempt_count() sub_preempt_count(1)
+#define preempt_count() (current_thread_info()->preempt_count)
+
#ifdef CONFIG_PREEMPT
asmlinkage void preempt_schedule(void);
@@ -94,9 +81,9 @@ do { \
/* For debugging and tracer internals only! */
#define add_preempt_count_notrace(val) \
- do { *preempt_count_ptr() += (val); } while (0)
+ do { preempt_count() += (val); } while (0)
#define sub_preempt_count_notrace(val) \
- do { *preempt_count_ptr() -= (val); } while (0)
+ do { preempt_count() -= (val); } while (0)
#define inc_preempt_count_notrace() add_preempt_count_notrace(1)
#define dec_preempt_count_notrace() sub_preempt_count_notrace(1)
diff --git a/include/linux/topology.h b/include/linux/topology.h
index c4b84dde95a..9138f31200a 100644
--- a/include/linux/topology.h
+++ b/include/linux/topology.h
@@ -88,7 +88,7 @@ int arch_update_cpu_topology(void);
#define SD_SIBLING_INIT (struct sched_domain) { \
.min_interval = 1, \
.max_interval = 2, \
- .busy_factor = 1, \
+ .busy_factor = 64, \
.imbalance_pct = 110, \
\
.flags = 1*SD_LOAD_BALANCE \
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
index 66cb5a0411b..046c74b014c 100644
--- a/include/linux/tracepoint.h
+++ b/include/linux/tracepoint.h
@@ -129,9 +129,6 @@ static inline void tracepoint_synchronize_unregister(void)
void *it_func; \
void *__data; \
\
- if (!cpu_online(raw_smp_processor_id())) \
- return; \
- \
if (!(cond)) \
return; \
prercu; \
diff --git a/include/linux/wait.h b/include/linux/wait.h
index 63648bbfa37..29321895d17 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -1046,5 +1046,33 @@ static inline int wait_on_bit_lock(void *word, int bit,
return 0;
return out_of_line_wait_on_bit_lock(word, bit, action, mode);
}
-
+
+/* 3.18 backport */
+extern int bit_wait_io(void *);
+
+/**
+ * wait_on_bit_io - wait for a bit to be cleared
+ * @word: the word being waited on, a kernel virtual address
+ * @bit: the bit of the word being waited on
+ * @mode: the task state to sleep in
+ *
+ * Use the standard hashed waitqueue table to wait for a bit
+ * to be cleared. This is similar to wait_on_bit(), but calls
+ * io_schedule() instead of schedule() for the actual waiting.
+ *
+ * Returned value will be zero if the bit was cleared, or non-zero
+ * if the process received a signal and the mode permitted wakeup
+ * on that signal.
+ */
+static inline int
+wait_on_bit_io(void *word, int bit, unsigned mode)
+{
+ might_sleep();
+ if (!test_bit(bit, word))
+ return 0;
+ return out_of_line_wait_on_bit(word, bit,
+ bit_wait_io,
+ mode);
+}
+
#endif
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index ac14ecec270..4dab847a1d7 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -304,35 +304,9 @@ enum {
WQ_CPU_INTENSIVE = 1 << 5, /* cpu instensive workqueue */
WQ_SYSFS = 1 << 6, /* visible in sysfs, see wq_sysfs_register() */
- /*
- * Per-cpu workqueues are generally preferred because they tend to
- * show better performance thanks to cache locality. Per-cpu
- * workqueues exclude the scheduler from choosing the CPU to
- * execute the worker threads, which has an unfortunate side effect
- * of increasing power consumption.
- *
- * The scheduler considers a CPU idle if it doesn't have any task
- * to execute and tries to keep idle cores idle to conserve power;
- * however, for example, a per-cpu work item scheduled from an
- * interrupt handler on an idle CPU will force the scheduler to
- * excute the work item on that CPU breaking the idleness, which in
- * turn may lead to more scheduling choices which are sub-optimal
- * in terms of power consumption.
- *
- * Workqueues marked with WQ_POWER_EFFICIENT are per-cpu by default
- * but become unbound if workqueue.power_efficient kernel param is
- * specified. Per-cpu workqueues which are identified to
- * contribute significantly to power-consumption are identified and
- * marked with this flag and enabling the power_efficient mode
- * leads to noticeable power saving at the cost of small
- * performance disadvantage.
- *
- * http://thread.gmane.org/gmane.linux.kernel/1480396
- */
- WQ_POWER_EFFICIENT = 1 << 7,
-
__WQ_DRAINING = 1 << 16, /* internal: workqueue is draining */
__WQ_ORDERED = 1 << 17, /* internal: workqueue is ordered */
+ __WQ_ORDERED_EXPLICIT = 1 << 18, /* internal: alloc_ordered_workqueue() */
WQ_MAX_ACTIVE = 512, /* I like 512, better ideas? */
WQ_MAX_UNBOUND_PER_CPU = 4, /* 4 * #cpus for unbound wq */
@@ -361,19 +335,11 @@ enum {
*
* system_freezable_wq is equivalent to system_wq except that it's
* freezable.
- *
- * *_power_efficient_wq are inclined towards saving power and converted
- * into WQ_UNBOUND variants if 'wq_power_efficient' is enabled; otherwise,
- * they are same as their non-power-efficient counterparts - e.g.
- * system_power_efficient_wq is identical to system_wq if
- * 'wq_power_efficient' is disabled. See WQ_POWER_EFFICIENT for more info.
*/
extern struct workqueue_struct *system_wq;
extern struct workqueue_struct *system_long_wq;
extern struct workqueue_struct *system_unbound_wq;
extern struct workqueue_struct *system_freezable_wq;
-extern struct workqueue_struct *system_power_efficient_wq;
-extern struct workqueue_struct *system_freezable_power_efficient_wq;
static inline struct workqueue_struct * __deprecated __system_nrt_wq(void)
{
@@ -443,7 +409,8 @@ __alloc_workqueue_key(const char *fmt, unsigned int flags, int max_active,
* Pointer to the allocated workqueue on success, %NULL on failure.
*/
#define alloc_ordered_workqueue(fmt, flags, args...) \
- alloc_workqueue(fmt, WQ_UNBOUND | __WQ_ORDERED | (flags), 1, ##args)
+ alloc_workqueue(fmt, WQ_UNBOUND | __WQ_ORDERED | \
+ __WQ_ORDERED_EXPLICIT | (flags), 1, ##args)
#define create_workqueue(name) \
alloc_workqueue((name), WQ_MEM_RECLAIM, 1)
diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h
index 21666fbdb72..3a4c37d9fb0 100644
--- a/include/net/fib_rules.h
+++ b/include/net/fib_rules.h
@@ -8,11 +8,6 @@
#include <net/flow.h>
#include <net/rtnetlink.h>
-struct fib_kuid_range {
- kuid_t start;
- kuid_t end;
-};
-
struct fib_rule {
struct list_head list;
atomic_t refcnt;
@@ -28,7 +23,8 @@ struct fib_rule {
struct fib_rule __rcu *ctarget;
char iifname[IFNAMSIZ];
char oifname[IFNAMSIZ];
- struct fib_kuid_range uid_range;
+ uid_t uid_start;
+ uid_t uid_end;
struct rcu_head rcu;
struct net * fr_net;
};
@@ -87,7 +83,8 @@ struct fib_rules_ops {
[FRA_FWMASK] = { .type = NLA_U32 }, \
[FRA_TABLE] = { .type = NLA_U32 }, \
[FRA_GOTO] = { .type = NLA_U32 }, \
- [FRA_UID_RANGE] = { .len = sizeof(struct fib_rule_uid_range) }
+ [FRA_UID_START] = { .type = NLA_U32 }, \
+ [FRA_UID_END] = { .type = NLA_U32 }
static inline void fib_rule_get(struct fib_rule *rule)
{
diff --git a/include/net/flow.h b/include/net/flow.h
index 15ecdd07e19..95fa38bda3a 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -10,7 +10,14 @@
#include <linux/socket.h>
#include <linux/in6.h>
#include <linux/atomic.h>
-#include <linux/uidgid.h>
+
+/*
+ * ifindex generation is per-net namespace, and loopback is
+ * always the 1st device in ns (see net_dev_init), thus any
+ * loopback device should get ifindex 1
+ */
+
+#define LOOPBACK_IFINDEX 1
/*
* ifindex generation is per-net namespace, and loopback is
@@ -32,7 +39,7 @@ struct flowi_common {
#define FLOWI_FLAG_CAN_SLEEP 0x02
#define FLOWI_FLAG_KNOWN_NH 0x04
__u32 flowic_secid;
- kuid_t flowic_uid;
+ uid_t flowic_uid;
};
union flowi_uli {
@@ -90,7 +97,7 @@ static inline void flowi4_init_output(struct flowi4 *fl4, int oif,
__u8 proto, __u8 flags,
__be32 daddr, __be32 saddr,
__be16 dport, __be16 sport,
- kuid_t uid)
+ uid_t uid)
{
fl4->flowi4_oif = oif;
fl4->flowi4_iif = LOOPBACK_IFINDEX;
diff --git a/include/net/ip.h b/include/net/ip.h
index c02d09be8ad..752697cd367 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -155,7 +155,7 @@ struct ip_reply_arg {
/* -1 if not needed */
int bound_dev_if;
u8 tos;
- kuid_t uid;
+ uid_t uid;
};
#define IP_REPLY_ARG_NOSRCCHECK 1
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index 30f068fafaa..8d977b34364 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -136,11 +136,10 @@ extern int rt6_route_rcv(struct net_device *dev,
const struct in6_addr *gwaddr);
extern void ip6_update_pmtu(struct sk_buff *skb, struct net *net, __be32 mtu,
- int oif, u32 mark, kuid_t uid);
+ int oif, u32 mark);
extern void ip6_sk_update_pmtu(struct sk_buff *skb, struct sock *sk,
__be32 mtu);
-extern void ip6_redirect(struct sk_buff *skb, struct net *net, int oif, u32 mark,
- kuid_t uid);
+extern void ip6_redirect(struct sk_buff *skb, struct net *net, int oif, u32 mark);
extern void ip6_sk_redirect(struct sk_buff *skb, struct sock *sk);
struct netlink_callback;
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index f3bb9e79fa2..1c581b99c64 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -849,6 +849,7 @@ extern int inet6_hash_connect(struct inet_timewait_death_row *death_row,
*/
extern const struct proto_ops inet6_stream_ops;
extern const struct proto_ops inet6_dgram_ops;
+extern const struct proto_ops inet6_sockraw_ops;
struct group_source_req;
struct group_filter;
diff --git a/include/net/iw_handler.h b/include/net/iw_handler.h
index 5d5a6a4732e..5af07a1ab0c 100644
--- a/include/net/iw_handler.h
+++ b/include/net/iw_handler.h
@@ -551,7 +551,8 @@ iwe_stream_add_point(struct iw_request_info *info, char *stream, char *ends,
memcpy(stream + lcp_len,
((char *) &iwe->u) + IW_EV_POINT_OFF,
IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
- memcpy(stream + point_len, extra, iwe->u.data.length);
+ if (iwe->u.data.length && extra)
+ memcpy(stream + point_len, extra, iwe->u.data.length);
stream += event_len;
}
return stream;
diff --git a/include/net/route.h b/include/net/route.h
index 4fe676279a4..43280f6fa56 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -52,6 +52,7 @@ struct rtable {
__u8 rt_uses_gateway;
int rt_iif;
+ uid_t rt_uid;
/* Info on neighbour */
__be32 rt_gateway;
@@ -142,7 +143,7 @@ static inline struct rtable *ip_route_output_ports(struct net *net, struct flowi
flowi4_init_output(fl4, oif, sk ? sk->sk_mark : 0, tos,
RT_SCOPE_UNIVERSE, proto,
sk ? inet_sk_flowi_flags(sk) : 0,
- daddr, saddr, dport, sport, sock_net_uid(net, sk));
+ daddr, saddr, dport, sport, sk ? sock_i_uid(sk) : 0);
if (sk)
security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
return ip_route_output_flow(net, fl4, sk);
@@ -254,7 +255,7 @@ static inline void ip_route_connect_init(struct flowi4 *fl4, __be32 dst, __be32
flowi4_init_output(fl4, oif, sk->sk_mark, tos, RT_SCOPE_UNIVERSE,
protocol, flow_flags, dst, src, dport, sport,
- sk->sk_uid);
+ sock_i_uid(sk));
}
static inline struct rtable *ip_route_connect(struct flowi4 *fl4,
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 845ab6decc4..ee81c68f24a 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -555,6 +555,8 @@ _sctp_walk_params((pos), (chunk), ntohs((chunk)->chunk_hdr.length), member)
#define _sctp_walk_params(pos, chunk, end, member)\
for (pos.v = chunk->member;\
+ (pos.v + offsetof(struct sctp_paramhdr, length) + sizeof(pos.p->length) <=\
+ (void *)chunk + end) &&\
pos.v <= (void *)chunk + end - ntohs(pos.p->length) &&\
ntohs(pos.p->length) >= sizeof(sctp_paramhdr_t);\
pos.v += WORD_ROUND(ntohs(pos.p->length)))
@@ -565,6 +567,8 @@ _sctp_walk_errors((err), (chunk_hdr), ntohs((chunk_hdr)->length))
#define _sctp_walk_errors(err, chunk_hdr, end)\
for (err = (sctp_errhdr_t *)((void *)chunk_hdr + \
sizeof(sctp_chunkhdr_t));\
+ ((void *)err + offsetof(sctp_errhdr_t, length) + sizeof(err->length) <=\
+ (void *)chunk_hdr + end) &&\
(void *)err <= (void *)chunk_hdr + end - ntohs(err->length) &&\
ntohs(err->length) >= sizeof(sctp_errhdr_t); \
err = (sctp_errhdr_t *)((void *)err + WORD_ROUND(ntohs(err->length))))
diff --git a/include/net/sctp/ulpevent.h b/include/net/sctp/ulpevent.h
index ca4693b4e09..00c0e5bf5d3 100644
--- a/include/net/sctp/ulpevent.h
+++ b/include/net/sctp/ulpevent.h
@@ -143,8 +143,12 @@ __u16 sctp_ulpevent_get_notification_type(const struct sctp_ulpevent *event);
static inline int sctp_ulpevent_type_enabled(__u16 sn_type,
struct sctp_event_subscribe *mask)
{
+ int offset = sn_type - SCTP_SN_TYPE_BASE;
char *amask = (char *) mask;
- return amask[sn_type - SCTP_SN_TYPE_BASE];
+
+ if (offset >= sizeof(struct sctp_event_subscribe))
+ return 0;
+ return amask[offset];
}
/* Given an event subscription, is this event enabled? */
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 809b3356f9c..eb3efd136f0 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1611,4 +1611,14 @@ struct tcp_request_sock_ops {
extern void tcp_v4_init(void);
extern void tcp_init(void);
+/* At how many jiffies into the future should the RTO fire? */
+static inline s32 tcp_rto_delta(const struct sock *sk)
+{
+ const struct sk_buff *skb = tcp_write_queue_head(sk);
+ const u32 rto = inet_csk(sk)->icsk_rto;
+ const u32 rto_time_stamp = TCP_SKB_CB(skb)->when + rto;
+
+ return (s32)(rto_time_stamp - tcp_time_stamp);
+}
+
#endif /* _TCP_H */
diff --git a/include/sound/msm-dts-eagle.h b/include/sound/msm-dts-eagle.h
deleted file mode 100644
index 2ef01136b7c..00000000000
--- a/include/sound/msm-dts-eagle.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 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.
- */
-
-#ifndef __MSM_DTS_EAGLE_H__
-#define __MSM_DTS_EAGLE_H__
-
-#include <linux/compat.h>
-#include <sound/soc.h>
-#include <sound/devdep_params.h>
-#include <sound/q6asm-v2.h>
-
-#ifdef CONFIG_COMPAT
-enum {
- DTS_EAGLE_IOCTL_GET_CACHE_SIZE32 = _IOR(0xF2, 0, __s32),
- DTS_EAGLE_IOCTL_SET_CACHE_SIZE32 = _IOW(0xF2, 1, __s32),
- DTS_EAGLE_IOCTL_GET_PARAM32 = _IOR(0xF2, 2, compat_uptr_t),
- DTS_EAGLE_IOCTL_SET_PARAM32 = _IOW(0xF2, 3, compat_uptr_t),
- DTS_EAGLE_IOCTL_SET_CACHE_BLOCK32 =
- _IOW(0xF2, 4, compat_uptr_t),
- DTS_EAGLE_IOCTL_SET_ACTIVE_DEVICE32 =
- _IOW(0xF2, 5, compat_uptr_t),
- DTS_EAGLE_IOCTL_GET_LICENSE32 =
- _IOR(0xF2, 6, compat_uptr_t),
- DTS_EAGLE_IOCTL_SET_LICENSE32 =
- _IOW(0xF2, 7, compat_uptr_t),
- DTS_EAGLE_IOCTL_SEND_LICENSE32 = _IOW(0xF2, 8, __s32),
- DTS_EAGLE_IOCTL_SET_VOLUME_COMMANDS32 = _IOW(0xF2, 9,
- compat_uptr_t),
-};
-#endif
-
-#ifdef CONFIG_DTS_EAGLE
-void msm_dts_ion_memmap(struct param_outband *po_);
-int msm_dts_eagle_enable_asm(struct audio_client *ac, u32 enable, int module);
-int msm_dts_eagle_enable_adm(int port_id, int copp_idx, u32 enable);
-void msm_dts_eagle_add_controls(struct snd_soc_platform *platform);
-int msm_dts_eagle_set_stream_gain(struct audio_client *ac,
- int lgain, int rgain);
-int msm_dts_eagle_handle_asm(struct dts_eagle_param_desc *depd, char *buf,
- bool for_pre, bool get, struct audio_client *ac,
- struct param_outband *po);
-int msm_dts_eagle_handle_adm(struct dts_eagle_param_desc *depd, char *buf,
- bool for_pre, bool get);
-int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg);
-int msm_dts_eagle_is_hpx_on(void);
-int msm_dts_eagle_init_pre(struct audio_client *ac);
-int msm_dts_eagle_deinit_pre(struct audio_client *ac);
-int msm_dts_eagle_init_post(int port_id, int copp_id);
-int msm_dts_eagle_deinit_post(int port_id, int topology);
-int msm_dts_eagle_init_master_module(struct audio_client *ac);
-int msm_dts_eagle_deinit_master_module(struct audio_client *ac);
-int msm_dts_eagle_pcm_new(struct snd_soc_pcm_runtime *runtime);
-void msm_dts_eagle_pcm_free(struct snd_pcm *pcm);
-int msm_dts_eagle_compat_ioctl(unsigned int cmd, unsigned long arg);
-#else
-static inline void msm_dts_ion_memmap(struct param_outband *po_)
-{
- pr_debug("%s\n", __func__);
-}
-static inline int msm_dts_eagle_enable_asm(struct audio_client *ac,
- u32 enable, int module)
-{
- return 0;
-}
-static inline int msm_dts_eagle_enable_adm(int port_id, int copp_idx,
- u32 enable)
-{
- return 0;
-}
-static inline void msm_dts_eagle_add_controls(struct snd_soc_platform *platform)
-{
-}
-static inline int msm_dts_eagle_set_stream_gain(struct audio_client *ac,
- int lgain, int rgain)
-{
- pr_debug("%s\n", __func__);
- return 0;
-}
-static inline int msm_dts_eagle_handle_asm(struct dts_eagle_param_desc *depd,
- char *buf, bool for_pre, bool get,
- struct audio_client *ac,
- struct param_outband *po)
-{
- return 0;
-}
-static inline int msm_dts_eagle_handle_adm(struct dts_eagle_param_desc *depd,
- char *buf, bool for_pre, bool get)
-{
- return 0;
-}
-static inline int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg)
-{
- return -EPERM;
-}
-static inline int msm_dts_eagle_is_hpx_on(void)
-{
- return 0;
-}
-static inline int msm_dts_eagle_init_pre(struct audio_client *ac)
-{
- return 0;
-}
-static inline int msm_dts_eagle_deinit_pre(struct audio_client *ac)
-{
- return 0;
-}
-static inline int msm_dts_eagle_init_post(int port_id, int coppid)
-{
- return 0;
-}
-static inline int msm_dts_eagle_deinit_post(int port_id, int topology)
-{
- return 0;
-}
-static inline int msm_dts_eagle_init_master_module(struct audio_client *ac)
-{
- return 0;
-}
-static inline int msm_dts_eagle_deinit_master_module(struct audio_client *ac)
-{
- return 0;
-}
-static inline int msm_dts_eagle_pcm_new(struct snd_soc_pcm_runtime *runtime)
-{
- pr_debug("%s\n", __func__);
- return 0;
-}
-static inline void msm_dts_eagle_pcm_free(struct snd_pcm *pcm)
-{
- pr_debug("%s\n", __func__);
-}
-static inline int msm_dts_eagle_compat_ioctl(unsigned int cmd,
- unsigned long arg)
-{
- return 0;
-}
-#endif
-
-#endif
diff --git a/include/sound/q6adm-v2.h b/include/sound/q6adm-v2.h
index d3a4da8e456..19b6309e2c1 100644
--- a/include/sound/q6adm-v2.h
+++ b/include/sound/q6adm-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -34,7 +34,6 @@ enum {
ADM_AUDVOL_CAL,
ADM_RTAC_INFO_CAL,
ADM_RTAC_APR_CAL,
- ADM_DTS_EAGLE,
ADM_SRS_TRUMEDIA,
ADM_MAX_CAL_TYPES
};
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index 7d99c0b5b78..8e271438f77 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -729,6 +729,7 @@ struct se_port_stat_grps {
struct se_lun {
#define SE_LUN_LINK_MAGIC 0xffff7771
u32 lun_link_magic;
+ bool lun_shutdown;
/* See transport_lun_status_table */
enum transport_lun_status_table lun_status;
u32 lun_access;
diff --git a/include/uapi/linux/android/binder.h b/include/uapi/linux/android/binder.h
index f60ebe918ff..fc512d01f77 100644
--- a/include/uapi/linux/android/binder.h
+++ b/include/uapi/linux/android/binder.h
@@ -131,6 +131,7 @@ enum {
/* struct binder_fd_array_object - object describing an array of fds in a buffer
* @hdr: common header structure
+ * @pad: padding to ensure correct alignment
* @num_fds: number of file descriptors in the buffer
* @parent: index in offset array to buffer holding the fd array
* @parent_offset: start offset of fd array in the buffer
@@ -151,6 +152,7 @@ enum {
*/
struct binder_fd_array_object {
struct binder_object_header hdr;
+ __u32 pad;
binder_size_t num_fds;
binder_size_t parent;
binder_size_t parent_offset;
diff --git a/include/uapi/linux/fib_rules.h b/include/uapi/linux/fib_rules.h
index 209abc4faf7..9dcdb6251cb 100644
--- a/include/uapi/linux/fib_rules.h
+++ b/include/uapi/linux/fib_rules.h
@@ -29,11 +29,6 @@ struct fib_rule_hdr {
__u32 flags;
};
-struct fib_rule_uid_range {
- __u32 start;
- __u32 end;
-};
-
enum {
FRA_UNSPEC,
FRA_DST, /* destination address */
@@ -54,9 +49,8 @@ enum {
FRA_TABLE, /* Extended table id */
FRA_FWMASK, /* mask for netfilter mark */
FRA_OIFNAME,
- FRA_PAD,
- FRA_L3MDEV, /* iif or oif is l3mdev goto its table */
- FRA_UID_RANGE, /* UID range */
+ FRA_UID_START, /* UID range */
+ FRA_UID_END,
__FRA_MAX
};
diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
index 99c4df8eb2e..b1a99e18b70 100644
--- a/include/uapi/linux/rtnetlink.h
+++ b/include/uapi/linux/rtnetlink.h
@@ -296,15 +296,8 @@ enum rtattr_type_t {
RTA_MP_ALGO, /* no longer used */
RTA_TABLE,
RTA_MARK,
- RTA_MFC_STATS,
- RTA_VIA,
- RTA_NEWDST,
- RTA_PREF,
- RTA_ENCAP_TYPE,
- RTA_ENCAP,
- RTA_EXPIRES,
- RTA_PAD,
RTA_UID,
+ RTA_MFC_STATS,
__RTA_MAX
};
diff --git a/init/main.c b/init/main.c
index c0f8b335f33..8e40280dc49 100644
--- a/init/main.c
+++ b/init/main.c
@@ -697,7 +697,7 @@ int __init_or_module do_one_initcall(initcall_t fn)
if (preempt_count() != count) {
sprintf(msgbuf, "preemption imbalance ");
- preempt_count_set(count);
+ preempt_count() = count;
}
if (irqs_disabled()) {
strlcat(msgbuf, "disabled interrupts ", sizeof(msgbuf));
diff --git a/kernel/audit.c b/kernel/audit.c
index 8ec45552b21..4dd7529b084 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -373,7 +373,7 @@ static void audit_printk_skb(struct sk_buff *skb)
if (nlh->nlmsg_type != AUDIT_EOE) {
if (printk_ratelimit())
- pr_debug(KERN_NOTICE "type=%d %s\n", nlh->nlmsg_type, data);
+ printk(KERN_NOTICE "type=%d %s\n", nlh->nlmsg_type, data);
else
audit_log_lost("printk limit exceeded\n");
}
@@ -690,7 +690,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
if (audit_enabled != AUDIT_OFF)
audit_log_config_change("audit_pid", new_pid, audit_pid, 1);
- audit_pid = 0;
+ audit_pid = new_pid;
audit_nlk_portid = NETLINK_CB(skb).portid;
}
if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) {
diff --git a/kernel/events/core.c b/kernel/events/core.c
index a4987ae1680..bcac08f9079 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -5483,6 +5483,9 @@ struct swevent_htable {
/* Recursion avoidance in each contexts */
int recursion[PERF_NR_CONTEXTS];
+
+ /* Keeps track of cpu being initialized/exited */
+ bool online;
};
static DEFINE_PER_CPU(struct swevent_htable, swevent_htable);
@@ -5729,8 +5732,14 @@ static int perf_swevent_add(struct perf_event *event, int flags)
hwc->state = !(flags & PERF_EF_START);
head = find_swevent_head(swhash, event);
- if (WARN_ON_ONCE(!head))
+ if (!head) {
+ /*
+ * We can race with cpu hotplug code. Do not
+ * WARN if the cpu just got unplugged.
+ */
+ WARN_ON_ONCE(swhash->online);
return -EINVAL;
+ }
hlist_add_head_rcu(&event->hlist_entry, head);
@@ -5802,6 +5811,7 @@ static int swevent_hlist_get_cpu(struct perf_event *event, int cpu)
int err = 0;
mutex_lock(&swhash->hlist_mutex);
+
if (!swevent_hlist_deref(swhash) && cpu_online(cpu)) {
struct swevent_hlist *hlist;
@@ -6996,37 +7006,6 @@ static void mutex_lock_double(struct mutex *a, struct mutex *b)
mutex_lock_nested(b, SINGLE_DEPTH_NESTING);
}
-/*
- * Variation on perf_event_ctx_lock_nested(), except we take two context
- * mutexes.
- */
-static struct perf_event_context *
-__perf_event_ctx_lock_double(struct perf_event *group_leader,
- struct perf_event_context *ctx)
-{
- struct perf_event_context *gctx;
-
-again:
- rcu_read_lock();
- gctx = ACCESS_ONCE(group_leader->ctx);
- if (!atomic_inc_not_zero(&gctx->refcount)) {
- rcu_read_unlock();
- goto again;
- }
- rcu_read_unlock();
-
- mutex_lock_double(&gctx->mutex, &ctx->mutex);
-
- if (group_leader->ctx != gctx) {
- mutex_unlock(&ctx->mutex);
- mutex_unlock(&gctx->mutex);
- put_ctx(gctx);
- goto again;
- }
-
- return gctx;
-}
-
/**
* sys_perf_event_open - open a performance event, associate it to a task/cpu
*
@@ -7241,31 +7220,13 @@ SYSCALL_DEFINE5(perf_event_open,
}
if (move_group) {
- gctx = __perf_event_ctx_lock_double(group_leader, ctx);
-
- /*
- * Check if we raced against another sys_perf_event_open() call
- * moving the software group underneath us.
- */
- if (!(group_leader->group_flags & PERF_GROUP_SOFTWARE)) {
- /*
- * If someone moved the group out from under us, check
- * if this new event wound up on the same ctx, if so
- * its the regular !move_group case, otherwise fail.
- */
- if (gctx != ctx) {
- err = -EINVAL;
- goto err_locked;
- } else {
- perf_event_ctx_unlock(group_leader, gctx);
- move_group = 0;
- }
- }
+ gctx = group_leader->ctx;
/*
* See perf_event_ctx_lock() for comments on the details
* of swizzling perf_event::ctx.
*/
+ mutex_lock_double(&gctx->mutex, &ctx->mutex);
mutex_lock(&gctx->mutex);
perf_remove_from_context(group_leader, false);
@@ -7308,7 +7269,7 @@ SYSCALL_DEFINE5(perf_event_open,
perf_unpin_context(ctx);
if (move_group) {
- perf_event_ctx_unlock(group_leader, gctx);
+ mutex_unlock(&gctx->mutex);
put_ctx(gctx);
}
mutex_unlock(&ctx->mutex);
@@ -7339,11 +7300,6 @@ SYSCALL_DEFINE5(perf_event_open,
fd_install(event_fd, event_file);
return event_fd;
-err_locked:
- if (move_group)
- perf_event_ctx_unlock(group_leader, gctx);
- mutex_unlock(&ctx->mutex);
- fput(event_file);
err_context:
perf_unpin_context(ctx);
put_ctx(ctx);
@@ -7957,6 +7913,7 @@ static void __cpuinit perf_event_init_cpu(int cpu)
struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu);
mutex_lock(&swhash->hlist_mutex);
+ swhash->online = true;
if (swhash->hlist_refcount > 0) {
struct swevent_hlist *hlist;
@@ -8057,6 +8014,13 @@ static void perf_event_start_swclock(int cpu)
static void perf_event_exit_cpu(int cpu)
{
+ struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu);
+
+ mutex_lock(&swhash->hlist_mutex);
+ swhash->online = false;
+ swevent_hlist_release(swhash);
+ mutex_unlock(&swhash->hlist_mutex);
+
perf_event_exit_cpu_context(cpu);
}
#else
diff --git a/kernel/extable.c b/kernel/extable.c
index 67460b93b1a..5ec4b6f861d 100644
--- a/kernel/extable.c
+++ b/kernel/extable.c
@@ -66,7 +66,7 @@ static inline int init_kernel_text(unsigned long addr)
return 0;
}
-int core_kernel_text(unsigned long addr)
+int notrace core_kernel_text(unsigned long addr)
{
if (addr >= (unsigned long)_stext &&
addr <= (unsigned long)_etext)
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index a9e5dc5f697..8069725ce90 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -12,7 +12,6 @@
#include <linux/seq_file.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
-#include <linux/mutex.h>
#include "internals.h"
@@ -349,29 +348,18 @@ void register_handler_proc(unsigned int irq, struct irqaction *action)
void register_irq_proc(unsigned int irq, struct irq_desc *desc)
{
- static DEFINE_MUTEX(register_lock);
char name [MAX_NAMELEN];
- if (!root_irq_dir || (desc->irq_data.chip == &no_irq_chip))
+ if (!root_irq_dir || (desc->irq_data.chip == &no_irq_chip) || desc->dir)
return;
- /*
- * irq directories are registered only when a handler is
- * added, not when the descriptor is created, so multiple
- * tasks might try to register at the same time.
- */
- mutex_lock(&register_lock);
-
- if (desc->dir)
- goto out_unlock;
-
memset(name, 0, MAX_NAMELEN);
sprintf(name, "%d", irq);
/* create /proc/irq/1234 */
desc->dir = proc_mkdir(name, root_irq_dir);
if (!desc->dir)
- goto out_unlock;
+ return;
#ifdef CONFIG_SMP
/* create /proc/irq/<irq>/smp_affinity */
@@ -396,9 +384,6 @@ void register_irq_proc(unsigned int irq, struct irq_desc *desc)
&irq_disable_depth_proc_fops, (void *)(long)irq);
proc_create_data("wake_depth", 0444, desc->dir,
&irq_wake_depth_proc_fops, (void *)(long)irq);
-
-out_unlock:
- mutex_unlock(&register_lock);
}
void unregister_irq_proc(unsigned int irq, struct irq_desc *desc)
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 15c2dffc1d2..079d567361f 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -270,26 +270,6 @@ config PM_GENERIC_DOMAINS
bool
depends on PM
-config WQ_POWER_EFFICIENT_DEFAULT
- bool "Enable workqueue power-efficient mode by default"
- depends on PM
- default n
- help
- Per-cpu workqueues are generally preferred because they show
- better performance thanks to cache locality; unfortunately,
- per-cpu workqueues tend to be more power hungry than unbound
- workqueues.
-
- Enabling workqueue.power_efficient kernel parameter makes the
- per-cpu workqueues which were observed to contribute
- significantly to power consumption unbound, leading to measurably
- lower power usage at the cost of small performance overhead.
-
- This config option determines whether workqueue.power_efficient
- is enabled by default.
-
- If in doubt, say N.
-
config PM_GENERIC_DOMAINS_SLEEP
def_bool y
depends on PM_SLEEP && PM_GENERIC_DOMAINS
diff --git a/kernel/rcu/srcu.c b/kernel/rcu/srcu.c
index 27b654950cc..01d5ccb8bfe 100644
--- a/kernel/rcu/srcu.c
+++ b/kernel/rcu/srcu.c
@@ -375,7 +375,7 @@ void call_srcu(struct srcu_struct *sp, struct rcu_head *head,
rcu_batch_queue(&sp->batch_queue, head);
if (!sp->running) {
sp->running = true;
- queue_delayed_work(system_power_efficient_wq, &sp->work, 0);
+ schedule_delayed_work(&sp->work, 0);
}
spin_unlock_irqrestore(&sp->queue_lock, flags);
}
@@ -631,8 +631,7 @@ static void srcu_reschedule(struct srcu_struct *sp)
}
if (pending)
- queue_delayed_work(system_power_efficient_wq,
- &sp->work, SRCU_INTERVAL);
+ schedule_delayed_work(&sp->work, SRCU_INTERVAL);
}
/*
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 19b8eea17ee..02da4984395 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -566,39 +566,6 @@ static inline void init_hrtick(void)
#endif /* CONFIG_SCHED_HRTICK */
/*
- * cmpxchg based fetch_or, macro so it works for different integer types
- */
-#define fetch_or(ptr, val) \
-({ typeof(*(ptr)) __old, __val = *(ptr); \
- for (;;) { \
- __old = cmpxchg((ptr), __val, __val | (val)); \
- if (__old == __val) \
- break; \
- __val = __old; \
- } \
- __old; \
-})
-
-#ifdef TIF_POLLING_NRFLAG
-/*
- * Atomically set TIF_NEED_RESCHED and test for TIF_POLLING_NRFLAG,
- * this avoids any races wrt polling state changes and thereby avoids
- * spurious IPIs.
- */
-static bool set_nr_and_not_polling(struct task_struct *p)
-{
- struct thread_info *ti = task_thread_info(p);
- return !(fetch_or(&ti->flags, _TIF_NEED_RESCHED) & _TIF_POLLING_NRFLAG);
-}
-#else
-static bool set_nr_and_not_polling(struct task_struct *p)
-{
- set_tsk_need_resched(p);
- return true;
-}
-#endif
-
-/*
* resched_task - mark a task 'to be rescheduled now'.
*
* On UP this means the setting of the need_resched flag, on SMP it
@@ -615,14 +582,15 @@ void resched_task(struct task_struct *p)
if (test_tsk_need_resched(p))
return;
- cpu = task_cpu(p);
+ set_tsk_need_resched(p);
- if (cpu == smp_processor_id()) {
- set_tsk_need_resched(p);
+ cpu = task_cpu(p);
+ if (cpu == smp_processor_id())
return;
- }
- if (set_nr_and_not_polling(p))
+ /* NEED_RESCHED must be visible before we test polling */
+ smp_mb();
+ if (!tsk_is_polling(p))
smp_send_reschedule(cpu);
}
@@ -3793,25 +3761,6 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags)
smp_rmb();
/*
- * Ensure we load p->on_cpu _after_ p->on_rq, otherwise it would be
- * possible to, falsely, observe p->on_cpu == 0.
- *
- * One must be running (->on_cpu == 1) in order to remove oneself
- * from the runqueue.
- *
- * [S] ->on_cpu = 1; [L] ->on_rq
- * UNLOCK rq->lock
- * RMB
- * LOCK rq->lock
- * [S] ->on_rq = 0; [L] ->on_cpu
- *
- * Pairs with the full barrier implied in the UNLOCK+LOCK on rq->lock
- * from the consecutive calls to schedule(); the first switching to our
- * task, the second putting it to sleep.
- */
- smp_rmb();
-
- /*
* If the owning (remote) cpu is still in the middle of schedule() with
* this task as prev, wait until its done referencing the task.
*/
@@ -4701,13 +4650,10 @@ static long calc_load_fold_active(struct rq *this_rq)
static unsigned long
calc_load(unsigned long load, unsigned long exp, unsigned long active)
{
- unsigned long newload;
-
- newload = load * exp + active * (FIXED_1 - exp);
- if (active >= load)
- newload += FIXED_1-1;
-
- return newload / FIXED_1;
+ load *= exp;
+ load += active * (FIXED_1 - exp);
+ load += 1UL << (FSHIFT - 1);
+ return load >> FSHIFT;
}
#ifdef CONFIG_NO_HZ_COMMON
@@ -5260,20 +5206,6 @@ unsigned long long task_sched_runtime(struct task_struct *p)
struct rq *rq;
u64 ns = 0;
-#if defined(CONFIG_64BIT) && defined(CONFIG_SMP)
- /*
- * 64-bit doesn't need locks to atomically read a 64bit value.
- * So we have a optimization chance when the task's delta_exec is 0.
- * Reading ->on_cpu is racy, but this is ok.
- *
- * If we race with it leaving cpu, we'll take a lock. So we're correct.
- * If we race with it entering cpu, unaccounted time is 0. This is
- * indistinguishable from the read occurring a few cycles earlier.
- */
- if (!p->on_cpu)
- return p->se.sum_exec_runtime;
-#endif
-
rq = task_rq_lock(p, &flags);
ns = p->se.sum_exec_runtime + do_task_delta_exec(p, rq);
task_rq_unlock(rq, p, &flags);
@@ -5368,7 +5300,7 @@ void __kprobes add_preempt_count(int val)
if (DEBUG_LOCKS_WARN_ON((preempt_count() < 0)))
return;
#endif
- add_preempt_count_notrace(val);
+ preempt_count() += val;
#ifdef CONFIG_DEBUG_PREEMPT
/*
* Spinlock count overflowing soon?
@@ -5399,7 +5331,7 @@ void __kprobes sub_preempt_count(int val)
if (preempt_count() == val)
trace_preempt_on(CALLER_ADDR0, get_parent_ip(CALLER_ADDR1));
- sub_preempt_count_notrace(val);
+ preempt_count() -= val;
}
EXPORT_SYMBOL(sub_preempt_count);
@@ -6462,8 +6394,6 @@ static void __setscheduler(struct rq *rq, struct task_struct *p,
if (policy == -1) /* setparam */
policy = p->policy;
- else
- policy &= ~SCHED_RESET_ON_FORK;
p->policy = policy;
@@ -6757,13 +6687,8 @@ change:
if (running)
p->sched_class->set_curr_task(rq);
- if (on_rq) {
- /*
- * We enqueue to tail when the priority of a task is
- * increased (user space view).
- */
- enqueue_task(rq, p, oldprio <= p->prio ? ENQUEUE_HEAD : 0);
- }
+ if (on_rq)
+ enqueue_task(rq, p, 0);
check_class_changed(rq, p, prev_class, oldprio);
task_rq_unlock(rq, p, &flags);
@@ -7700,7 +7625,7 @@ void show_state_filter(unsigned long state_filter)
" task PC stack pid father\n");
#endif
rcu_read_lock();
- for_each_process_thread(g, p) {
+ do_each_thread(g, p) {
/*
* reset the NMI-timeout, listing all files on a slow
* console might take a lot of time:
@@ -7708,7 +7633,7 @@ void show_state_filter(unsigned long state_filter)
touch_nmi_watchdog();
if (!state_filter || (p->state & state_filter))
sched_show_task(p);
- }
+ } while_each_thread(g, p);
touch_all_softlockup_watchdogs();
@@ -10290,7 +10215,7 @@ void normalize_rt_tasks(void)
struct rq *rq;
read_lock_irqsave(&tasklist_lock, flags);
- for_each_process_thread(g, p) {
+ do_each_thread(g, p) {
/*
* Only normalize user tasks:
*/
@@ -10321,7 +10246,8 @@ void normalize_rt_tasks(void)
__task_rq_unlock(rq);
raw_spin_unlock(&p->pi_lock);
- }
+ } while_each_thread(g, p);
+
read_unlock_irqrestore(&tasklist_lock, flags);
}
@@ -10507,10 +10433,10 @@ static inline int tg_has_rt_tasks(struct task_group *tg)
{
struct task_struct *g, *p;
- for_each_process_thread(g, p) {
+ do_each_thread(g, p) {
if (rt_task(p) && task_rq(p)->rt.tg == tg)
return 1;
- }
+ } while_each_thread(g, p);
return 0;
}
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
index e62356250b1..135e7793350 100644
--- a/kernel/sched/cputime.c
+++ b/kernel/sched/cputime.c
@@ -160,8 +160,10 @@ void account_user_time(struct task_struct *p, cputime_t cputime,
/* Account for user time used */
acct_account_cputime(p);
+#ifdef CONFIG_CPU_FREQ_STAT
/* Account power usage for user time */
acct_update_power(p, cputime);
+#endif
}
/*
@@ -213,8 +215,10 @@ void __account_system_time(struct task_struct *p, cputime_t cputime,
/* Account for system time used */
acct_account_cputime(p);
+#ifdef CONFIG_CPU_FREQ_STAT
/* Account power usage for system time */
acct_update_power(p, cputime);
+#endif
}
/*
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 8f3693aec2c..7347861b2de 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -5544,10 +5544,6 @@ find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu)
int idlest = -1;
int i;
- /* Check if we have any choice: */
- if (group->group_weight == 1)
- return cpumask_first(sched_group_cpus(group));
-
/* Traverse only the allowed CPUs */
for_each_cpu_and(i, sched_group_cpus(group), tsk_cpus_allowed(p)) {
load = weighted_cpuload(i);
@@ -7902,6 +7898,7 @@ void idle_balance(int this_cpu, struct rq *this_rq)
continue;
if (sd->flags & SD_BALANCE_NEWIDLE) {
+ /* If we've pulled tasks over stop searching: */
pulled_task = load_balance(balance_cpu, balance_rq,
sd, CPU_NEWLY_IDLE, &balance);
}
@@ -7909,11 +7906,7 @@ void idle_balance(int this_cpu, struct rq *this_rq)
interval = msecs_to_jiffies(sd->balance_interval);
if (time_after(next_balance, sd->last_balance + interval))
next_balance = sd->last_balance + interval;
- /*
- * Stop searching for tasks to pull if there are
- * now runnable tasks on this rq.
- */
- if (pulled_task || this_rq->nr_running > 0) {
+ if (pulled_task) {
balance_rq->idle_stamp = 0;
break;
}
diff --git a/kernel/sched/wait.c b/kernel/sched/wait.c
index 6698e0c04ea..bca170ef386 100644
--- a/kernel/sched/wait.c
+++ b/kernel/sched/wait.c
@@ -287,3 +287,12 @@ wait_queue_head_t *bit_waitqueue(void *word, int bit)
return &zone->wait_table[hash_long(val, zone->wait_table_bits)];
}
EXPORT_SYMBOL(bit_waitqueue);
+
+__sched int bit_wait_io(void *word)
+{
+ if (signal_pending_state(current->state, current))
+ return 1;
+ io_schedule();
+ return 0;
+}
+EXPORT_SYMBOL(bit_wait_io);
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 3c7b56ecf23..96a4c2828ce 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -104,7 +104,7 @@ static void __local_bh_disable(unsigned long ip, unsigned int cnt)
* We must manually increment preempt_count here and manually
* call the trace_preempt_off later.
*/
- add_preempt_count_notrace(cnt);
+ preempt_count() += cnt;
/*
* Were softirqs turned off above:
*/
@@ -256,7 +256,7 @@ restart:
" exited with %08x?\n", vec_nr,
softirq_to_name[vec_nr], h->action,
prev_count, preempt_count());
- preempt_count_set(prev_count);
+ preempt_count() = prev_count;
}
rcu_bh_qs(cpu);
diff --git a/kernel/sys.c b/kernel/sys.c
index 60eb8d9dee4..1e63f33beb5 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -2405,6 +2405,26 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
else
return -EINVAL;
break;
+ case PR_SET_TIMERSLACK_PID:
+ if (current->pid != (pid_t)arg3 &&
+ !capable(CAP_SYS_NICE))
+ return -EPERM;
+ rcu_read_lock();
+ tsk = find_task_by_pid_ns((pid_t)arg3, &init_pid_ns);
+ if (tsk == NULL) {
+ rcu_read_unlock();
+ return -EINVAL;
+ }
+ get_task_struct(tsk);
+ rcu_read_unlock();
+ if (arg2 <= 0)
+ tsk->timer_slack_ns =
+ tsk->default_timer_slack_ns;
+ else
+ tsk->timer_slack_ns = arg2;
+ put_task_struct(tsk);
+ error = 0;
+ break;
default:
return -EINVAL;
}
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 555616d7a8d..ceb9091d73d 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -129,7 +129,6 @@ static int zero;
static int __maybe_unused one = 1;
static int __maybe_unused two = 2;
static int __maybe_unused three = 3;
-static int __maybe_unused four = 4;
static unsigned long one_ul = 1;
static int one_hundred = 100;
#ifdef CONFIG_PRINTK
@@ -1019,7 +1018,7 @@ static struct ctl_table kern_table[] = {
.mode = 0644,
.proc_handler = proc_dointvec_minmax_sysadmin,
.extra1 = &zero,
- .extra2 = &four,
+ .extra2 = &two,
},
#endif
{
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index 105d5d409b7..6211d5d6d46 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -514,13 +514,12 @@ static void sync_cmos_clock(struct work_struct *work)
next.tv_sec++;
next.tv_nsec -= NSEC_PER_SEC;
}
- queue_delayed_work(system_power_efficient_wq,
- &sync_cmos_work, timespec_to_jiffies(&next));
+ schedule_delayed_work(&sync_cmos_work, timespec_to_jiffies(&next));
}
void ntp_notify_cmos_timer(void)
{
- queue_delayed_work(system_power_efficient_wq, &sync_cmos_work, 0);
+ schedule_delayed_work(&sync_cmos_work, 0);
}
#else
diff --git a/kernel/timer.c b/kernel/timer.c
index 87731456d8a..09b86498428 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -1150,7 +1150,7 @@ static int cascade(struct tvec_base *base, struct tvec *tv, int index)
static void call_timer_fn(struct timer_list *timer, void (*fn)(unsigned long),
unsigned long data)
{
- int count = preempt_count();
+ int preempt_count = preempt_count();
#ifdef CONFIG_LOCKDEP
/*
@@ -1177,16 +1177,16 @@ static void call_timer_fn(struct timer_list *timer, void (*fn)(unsigned long),
lock_map_release(&lockdep_map);
- if (count != preempt_count()) {
+ if (preempt_count != preempt_count()) {
WARN_ONCE(1, "timer: %pF preempt leak: %08x -> %08x\n",
- fn, count, preempt_count());
+ fn, preempt_count, preempt_count());
/*
* Restore the preempt count. That gives us a decent
* chance to survive and extract information. If the
* callback kept a lock held, bad luck, but not worse
* than the BUG() we had.
*/
- preempt_count_set(count);
+ preempt_count() = preempt_count;
}
}
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index a0ed8b55354..18d8047c595 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -3068,11 +3068,17 @@ static int tracing_open(struct inode *inode, struct file *file)
/* If this file was open for write, then erase contents */
if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
int cpu = tracing_get_cpu(inode);
+ struct trace_buffer *trace_buf = &tr->trace_buffer;
+
+#ifdef CONFIG_TRACER_MAX_TRACE
+ if (tr->current_trace->print_max)
+ trace_buf = &tr->max_buffer;
+#endif
if (cpu == RING_BUFFER_ALL_CPUS)
- tracing_reset_online_cpus(&tr->trace_buffer);
+ tracing_reset_online_cpus(trace_buf);
else
- tracing_reset(&tr->trace_buffer, cpu);
+ tracing_reset(trace_buf, cpu);
}
if (file->f_mode & FMODE_READ) {
@@ -4664,7 +4670,7 @@ static ssize_t tracing_clock_write(struct file *filp, const char __user *ubuf,
tracing_reset_online_cpus(&tr->trace_buffer);
#ifdef CONFIG_TRACER_MAX_TRACE
- if (tr->flags & TRACE_ARRAY_FL_GLOBAL && tr->max_buffer.buffer)
+ if (tr->max_buffer.buffer)
ring_buffer_set_clock(tr->max_buffer.buffer, trace_clocks[i].func);
tracing_reset_online_cpus(&tr->max_buffer);
#endif
diff --git a/kernel/trace/trace_printk.c b/kernel/trace/trace_printk.c
index 7be4d67cecb..3f4ff304a70 100644
--- a/kernel/trace/trace_printk.c
+++ b/kernel/trace/trace_printk.c
@@ -277,10 +277,7 @@ static int t_show(struct seq_file *m, void *v)
const char *str = *fmt;
int i;
- if (!*fmt)
- return 0;
-
- seq_printf(m, "0x%lx : \"", *(unsigned long *)fmt);
+ seq_printf(m, "0x%lx : \"", 0L);
/*
* Tabs and new lines need to be converted.
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 4bd68353f49..dd1a51dc358 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -273,15 +273,6 @@ static cpumask_var_t *wq_numa_possible_cpumask;
static bool wq_disable_numa;
module_param_named(disable_numa, wq_disable_numa, bool, 0444);
-/* see the comment above the definition of WQ_POWER_EFFICIENT */
-#ifdef CONFIG_WQ_POWER_EFFICIENT_DEFAULT
-static bool wq_power_efficient = true;
-#else
-static bool wq_power_efficient;
-#endif
-
-module_param_named(power_efficient, wq_power_efficient, bool, 0444);
-
static bool wq_numa_enabled; /* unbound NUMA affinity enabled */
/* buf for wq_update_unbound_numa_attrs(), protected by CPU hotplug exclusion */
@@ -318,10 +309,6 @@ struct workqueue_struct *system_unbound_wq __read_mostly;
EXPORT_SYMBOL_GPL(system_unbound_wq);
struct workqueue_struct *system_freezable_wq __read_mostly;
EXPORT_SYMBOL_GPL(system_freezable_wq);
-struct workqueue_struct *system_power_efficient_wq __read_mostly;
-EXPORT_SYMBOL_GPL(system_power_efficient_wq);
-struct workqueue_struct *system_freezable_power_efficient_wq __read_mostly;
-EXPORT_SYMBOL_GPL(system_freezable_power_efficient_wq);
static int worker_thread(void *__worker);
static void copy_workqueue_attrs(struct workqueue_attrs *to,
@@ -3414,7 +3401,7 @@ int workqueue_sysfs_register(struct workqueue_struct *wq)
* attributes breaks ordering guarantee. Disallow exposing ordered
* workqueues.
*/
- if (WARN_ON(wq->flags & __WQ_ORDERED))
+ if (WARN_ON(wq->flags & __WQ_ORDERED_EXPLICIT))
return -EINVAL;
wq->wq_dev = wq_dev = kzalloc(sizeof(*wq_dev), GFP_KERNEL);
@@ -3979,8 +3966,12 @@ int apply_workqueue_attrs(struct workqueue_struct *wq,
return -EINVAL;
/* creating multiple pwqs breaks ordering guarantee */
- if (WARN_ON((wq->flags & __WQ_ORDERED) && !list_empty(&wq->pwqs)))
- return -EINVAL;
+ if (!list_empty(&wq->pwqs)) {
+ if (WARN_ON(wq->flags & __WQ_ORDERED_EXPLICIT))
+ return -EINVAL;
+
+ wq->flags &= ~__WQ_ORDERED;
+ }
pwq_tbl = kzalloc(wq_numa_tbl_len * sizeof(pwq_tbl[0]), GFP_KERNEL);
new_attrs = alloc_workqueue_attrs(GFP_KERNEL);
@@ -4228,9 +4219,15 @@ struct workqueue_struct *__alloc_workqueue_key(const char *fmt,
struct workqueue_struct *wq;
struct pool_workqueue *pwq;
- /* see the comment above the definition of WQ_POWER_EFFICIENT */
- if ((flags & WQ_POWER_EFFICIENT) && wq_power_efficient)
- flags |= WQ_UNBOUND;
+ /*
+ * Unbound && max_active == 1 used to imply ordered, which is no
+ * longer the case on NUMA machines due to per-node pools. While
+ * alloc_ordered_workqueue() is the right way to create an ordered
+ * workqueue, keep the previous behavior to avoid subtle breakages
+ * on NUMA.
+ */
+ if ((flags & WQ_UNBOUND) && max_active == 1)
+ flags |= __WQ_ORDERED;
/* allocate wq and format name */
if (flags & WQ_UNBOUND)
@@ -4420,13 +4417,14 @@ void workqueue_set_max_active(struct workqueue_struct *wq, int max_active)
struct pool_workqueue *pwq;
/* disallow meddling with max_active for ordered workqueues */
- if (WARN_ON(wq->flags & __WQ_ORDERED))
+ if (WARN_ON(wq->flags & __WQ_ORDERED_EXPLICIT))
return;
max_active = wq_clamp_max_active(max_active, wq->flags, wq->name);
mutex_lock(&wq->mutex);
+ wq->flags &= ~__WQ_ORDERED;
wq->saved_max_active = max_active;
for_each_pwq(pwq, wq)
@@ -5141,15 +5139,8 @@ static int __init init_workqueues(void)
WQ_UNBOUND_MAX_ACTIVE);
system_freezable_wq = alloc_workqueue("events_freezable",
WQ_FREEZABLE, 0);
- system_power_efficient_wq = alloc_workqueue("events_power_efficient",
- WQ_POWER_EFFICIENT, 0);
- system_freezable_power_efficient_wq = alloc_workqueue("events_freezable_power_efficient",
- WQ_FREEZABLE | WQ_POWER_EFFICIENT,
- 0);
BUG_ON(!system_wq || !system_highpri_wq || !system_long_wq ||
- !system_unbound_wq || !system_freezable_wq ||
- !system_power_efficient_wq ||
- !system_freezable_power_efficient_wq);
+ !system_unbound_wq || !system_freezable_wq);
return 0;
}
early_initcall(init_workqueues);
diff --git a/lib/cmdline.c b/lib/cmdline.c
index eb6791188cf..efc35fbce78 100644
--- a/lib/cmdline.c
+++ b/lib/cmdline.c
@@ -22,14 +22,14 @@
* the values[M, M+1, ..., N] into the ints array in get_options.
*/
-static int get_range(char **str, int *pint)
+static int get_range(char **str, int *pint, int n)
{
int x, inc_counter, upper_range;
(*str)++;
upper_range = simple_strtol((*str), NULL, 0);
inc_counter = upper_range - *pint;
- for (x = *pint; x < upper_range; x++)
+ for (x = *pint; n && x < upper_range; x++, n--)
*pint++ = x;
return inc_counter;
}
@@ -95,7 +95,7 @@ char *get_options(const char *str, int nints, int *ints)
break;
if (res == 3) {
int range_nums;
- range_nums = get_range((char **)&str, ints + i);
+ range_nums = get_range((char **)&str, ints + i, nints - i);
if (range_nums < 0)
break;
/*
diff --git a/lib/digsig.c b/lib/digsig.c
index 2f31e6a45f0..ae703dfc973 100644
--- a/lib/digsig.c
+++ b/lib/digsig.c
@@ -86,6 +86,12 @@ static int digsig_verify_rsa(struct key *key,
down_read(&key->sem);
ukp = key->payload.data;
+ if (!ukp) {
+ /* key was revoked before we acquired its semaphore */
+ err = -EKEYREVOKED;
+ goto err1;
+ }
+
if (ukp->datalen < sizeof(*pkh))
goto err1;
diff --git a/lib/int_sqrt.c b/lib/int_sqrt.c
index 3d7a3e0237c..1ef4cc34497 100644
--- a/lib/int_sqrt.c
+++ b/lib/int_sqrt.c
@@ -14,34 +14,25 @@
*
* A very rough approximation to the sqrt() function.
*/
-inline unsigned long int_sqrt(unsigned long x)
+unsigned long int_sqrt(unsigned long x)
{
- register unsigned long tmp;
- register unsigned long place;
- register unsigned long root = 0;
+ unsigned long b, m, y = 0;
if (x <= 1)
return x;
- place = 1UL << (BITS_PER_LONG - 2);
+ m = 1UL << (BITS_PER_LONG - 2);
+ while (m != 0) {
+ b = y + m;
+ y >>= 1;
- do{
- place >>= 2;
- }while(place > x);
-
- do {
- tmp = root + place;
- root >>= 1;
-
- if (x >= tmp)
- {
- x -= tmp;
- root += place;
+ if (x >= b) {
+ x -= b;
+ y += m;
}
- place >>= 2;
- }while (place != 0);
+ m >>= 2;
+ }
- return root;
+ return y;
}
EXPORT_SYMBOL(int_sqrt);
-
diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c
index 51b88ec0fe7..c3eb261a7df 100644
--- a/lib/locking-selftest.c
+++ b/lib/locking-selftest.c
@@ -979,7 +979,7 @@ static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask)
* Some tests (e.g. double-unlock) might corrupt the preemption
* count, so restore it:
*/
- preempt_count_set(saved_preempt_count);
+ preempt_count() = saved_preempt_count;
#ifdef CONFIG_TRACE_IRQFLAGS
if (softirq_count())
current->softirqs_enabled = 0;
diff --git a/lib/lz4/lz4_decompress.c b/lib/lz4/lz4_decompress.c
index 6324d6d6d86..b16db3b9e62 100644
--- a/lib/lz4/lz4_decompress.c
+++ b/lib/lz4/lz4_decompress.c
@@ -47,6 +47,11 @@
#include "lz4defs.h"
+static const int dec32table[] = {0, 3, 2, 3, 0, 0, 0, 0};
+#if LZ4_ARCH64
+static const int dec64table[] = {0, 0, 0, -1, 0, 1, 2, 3};
+#endif
+
static int lz4_uncompress(const char *source, char *dest, int osize)
{
const BYTE *ip = (const BYTE *) source;
@@ -56,10 +61,6 @@ static int lz4_uncompress(const char *source, char *dest, int osize)
BYTE *cpy;
unsigned token;
size_t length;
- size_t dec32table[] = {0, 3, 2, 3, 0, 0, 0, 0};
-#if LZ4_ARCH64
- size_t dec64table[] = {0, 0, 0, -1, 0, 1, 2, 3};
-#endif
while (1) {
@@ -116,7 +117,7 @@ static int lz4_uncompress(const char *source, char *dest, int osize)
/* copy repeated sequence */
if (unlikely((op - ref) < STEPSIZE)) {
#if LZ4_ARCH64
- size_t dec64 = dec64table[op - ref];
+ int dec64 = dec64table[op - ref];
#else
const int dec64 = 0;
#endif
@@ -139,6 +140,13 @@ static int lz4_uncompress(const char *source, char *dest, int osize)
/* Error: request to write beyond destination buffer */
if (cpy > oend)
goto _output_error;
+#if LZ4_ARCH64
+ if ((ref + COPYLENGTH) > oend)
+#else
+ if ((ref + COPYLENGTH) > oend ||
+ (op + COPYLENGTH) > oend)
+#endif
+ goto _output_error;
LZ4_SECURECOPY(ref, op, (oend - COPYLENGTH));
while (op < cpy)
*op++ = *ref++;
@@ -174,11 +182,6 @@ static int lz4_uncompress_unknownoutputsize(const char *source, char *dest,
BYTE * const oend = op + maxoutputsize;
BYTE *cpy;
- size_t dec32table[] = {0, 3, 2, 3, 0, 0, 0, 0};
-#if LZ4_ARCH64
- size_t dec64table[] = {0, 0, 0, -1, 0, 1, 2, 3};
-#endif
-
/* Main Loop */
while (ip < iend) {
@@ -192,6 +195,8 @@ static int lz4_uncompress_unknownoutputsize(const char *source, char *dest,
int s = 255;
while ((ip < iend) && (s == 255)) {
s = *ip++;
+ if (unlikely(length > (size_t)(length + s)))
+ goto _output_error;
length += s;
}
}
@@ -232,6 +237,8 @@ static int lz4_uncompress_unknownoutputsize(const char *source, char *dest,
if (length == ML_MASK) {
while (ip < iend) {
int s = *ip++;
+ if (unlikely(length > (size_t)(length + s)))
+ goto _output_error;
length += s;
if (s == 255)
continue;
@@ -242,7 +249,7 @@ static int lz4_uncompress_unknownoutputsize(const char *source, char *dest,
/* copy repeated sequence */
if (unlikely((op - ref) < STEPSIZE)) {
#if LZ4_ARCH64
- size_t dec64 = dec64table[op - ref];
+ int dec64 = dec64table[op - ref];
#else
const int dec64 = 0;
#endif
@@ -263,7 +270,13 @@ static int lz4_uncompress_unknownoutputsize(const char *source, char *dest,
if (cpy > oend - COPYLENGTH) {
if (cpy > oend)
goto _output_error; /* write outside of buf */
-
+#if LZ4_ARCH64
+ if ((ref + COPYLENGTH) > oend)
+#else
+ if ((ref + COPYLENGTH) > oend ||
+ (op + COPYLENGTH) > oend)
+#endif
+ goto _output_error;
LZ4_SECURECOPY(ref, op, (oend - COPYLENGTH));
while (op < cpy)
*op++ = *ref++;
@@ -284,7 +297,7 @@ static int lz4_uncompress_unknownoutputsize(const char *source, char *dest,
/* write overflow error detected */
_output_error:
- return (int) (-(((char *) ip) - source));
+ return -1;
}
int lz4_decompress(const unsigned char *src, size_t *src_len,
diff --git a/lib/lz4/lz4defs.h b/lib/lz4/lz4defs.h
index abcecdc2d0f..697e08287e4 100644
--- a/lib/lz4/lz4defs.h
+++ b/lib/lz4/lz4defs.h
@@ -11,8 +11,7 @@
/*
* Detects 64 bits mode
*/
-#if (defined(__x86_64__) || defined(__x86_64) || defined(__amd64__) \
- || defined(__ppc64__) || defined(__LP64__))
+#if defined(CONFIG_64BIT)
#define LZ4_ARCH64 1
#else
#define LZ4_ARCH64 0
@@ -21,13 +20,12 @@
/*
* Architecture-specific macros
*/
+#define ARM_EFFICIENT_UNALIGNED_ACCESS
#define BYTE u8
typedef struct _U16_S { u16 v; } U16_S;
typedef struct _U32_S { u32 v; } U32_S;
typedef struct _U64_S { u64 v; } U64_S;
-#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) \
- || defined(CONFIG_ARM) && __LINUX_ARM_ARCH__ >= 6 \
- && defined(ARM_EFFICIENT_UNALIGNED_ACCESS)
+#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
#define A16(x) (((U16_S *)(x))->v)
#define A32(x) (((U32_S *)(x))->v)
@@ -35,6 +33,10 @@ typedef struct _U64_S { u64 v; } U64_S;
#define PUT4(s, d) (A32(d) = A32(s))
#define PUT8(s, d) (A64(d) = A64(s))
+
+#define LZ4_READ_LITTLEENDIAN_16(d, s, p) \
+ (d = s - A16(p))
+
#define LZ4_WRITE_LITTLEENDIAN_16(p, v) \
do { \
A16(p) = v; \
@@ -51,10 +53,13 @@ typedef struct _U64_S { u64 v; } U64_S;
#define PUT8(s, d) \
put_unaligned(get_unaligned((const u64 *) s), (u64 *) d)
-#define LZ4_WRITE_LITTLEENDIAN_16(p, v) \
- do { \
- put_unaligned(v, (u16 *)(p)); \
- p += 2; \
+#define LZ4_READ_LITTLEENDIAN_16(d, s, p) \
+ (d = s - get_unaligned_le16(p))
+
+#define LZ4_WRITE_LITTLEENDIAN_16(p, v) \
+ do { \
+ put_unaligned_le16(v, (u16 *)(p)); \
+ p += 2; \
} while (0)
#endif
@@ -140,9 +145,6 @@ typedef struct _U64_S { u64 v; } U64_S;
#endif
-#define LZ4_READ_LITTLEENDIAN_16(d, s, p) \
- (d = s - get_unaligned_le16(p))
-
#define LZ4_WILDCOPY(s, d, e) \
do { \
LZ4_COPYPACKET(s, d); \
diff --git a/lib/smp_processor_id.c b/lib/smp_processor_id.c
index 04abe53f12a..4c0d0e51d49 100644
--- a/lib/smp_processor_id.c
+++ b/lib/smp_processor_id.c
@@ -9,9 +9,10 @@
notrace unsigned int debug_smp_processor_id(void)
{
+ unsigned long preempt_count = preempt_count();
int this_cpu = raw_smp_processor_id();
- if (likely(preempt_count()))
+ if (likely(preempt_count))
goto out;
if (irqs_disabled())
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 7f5a08b99f4..378445329a7 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -377,32 +377,6 @@ struct printf_spec {
s16 precision; /* # of digits/chars */
};
-int kptr_restrict __read_mostly = 4;
-
-/*
- * Always cleanse %p and %pK specifiers
- */
-static inline int kptr_restrict_always_cleanse_pointers(void)
-{
- return kptr_restrict >= 3;
-}
-
-/*
- * Always cleanse physical addresses (%pa* specifiers)
- */
-static inline int kptr_restrict_cleanse_addresses(void)
-{
- return kptr_restrict >= 4;
-}
-
-/*
- * Always cleanse resource addresses (%p[rR] specifiers)
- */
-static inline int kptr_restrict_cleanse_resources(void)
-{
- return kptr_restrict >= 4;
-}
-
static noinline_for_stack
char *number(char *buf, char *end, unsigned long long num,
struct printf_spec spec)
@@ -646,7 +620,6 @@ char *resource_string(char *buf, char *end, struct resource *res,
char *p = sym, *pend = sym + sizeof(sym);
int decode = (fmt[0] == 'R') ? 1 : 0;
- int cleanse = kptr_restrict_cleanse_resources();
const struct printf_spec *specp;
*p++ = '[';
@@ -670,11 +643,10 @@ char *resource_string(char *buf, char *end, struct resource *res,
specp = &mem_spec;
decode = 0;
}
- p = number(p, pend, cleanse ? 0UL : res->start, *specp);
+ p = number(p, pend, res->start, *specp);
if (res->start != res->end) {
*p++ = '-';
- p = number(p, pend,
- cleanse ? res->end - res->start : res->end, *specp);
+ p = number(p, pend, res->end, *specp);
}
if (decode) {
if (res->flags & IORESOURCE_MEM_64)
@@ -693,7 +665,6 @@ char *resource_string(char *buf, char *end, struct resource *res,
*p = '\0';
return string(buf, end, sym, spec);
-
}
static noinline_for_stack
@@ -1011,6 +982,8 @@ char *netdev_feature_string(char *buf, char *end, const u8 *addr,
return number(buf, end, *(const netdev_features_t *)addr, spec);
}
+int kptr_restrict __read_mostly;
+
/*
* Show a '%p' thing. A kernel extension is that the '%p' is followed
* by an extra set of alphanumeric characters that are extended format
@@ -1058,7 +1031,6 @@ char *netdev_feature_string(char *buf, char *end, const u8 *addr,
* Do not use this feature without some mechanism to verify the
* correctness of the format string and va_list arguments.
* - 'K' For a kernel pointer that should be hidden from unprivileged users
- * - 'P' For a kernel pointer that should be shown to all users
* - 'NF' For a netdev_features_t
* - 'h[CDN]' For a variable-length buffer, it prints it as a hex string with
* a certain separator (' ' by default):
@@ -1072,15 +1044,6 @@ char *netdev_feature_string(char *buf, char *end, const u8 *addr,
* Note: The difference between 'S' and 'F' is that on ia64 and ppc64
* function pointers are really function descriptors, which contain a
* pointer to the real address.
- *
- * Note: That for kptr_restrict set to 3, %p and %pK have the same
- * meaning.
- *
- * Note: That for kptr_restrict set to 4, %pa will null out the physical
- * address.
- *
- * Note: That for kptr_restrict set to 4, %p[rR] will null out the memory
- * address.
*/
static noinline_for_stack
char *pointer(const char *fmt, char *buf, char *end, void *ptr,
@@ -1088,7 +1051,7 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
{
int default_width = 2 * sizeof(void *) + (spec.flags & SPECIAL ? 2 : 0);
- if (!ptr && *fmt != 'K' && !kptr_restrict_always_cleanse_pointers()) {
+ if (!ptr && *fmt != 'K') {
/*
* Print (null) with the same width as a pointer so it makes
* tabular output look nice.
@@ -1145,79 +1108,60 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
va_end(va);
return buf;
}
- case 'N':
- switch (fmt[1]) {
- case 'F':
- return netdev_feature_string(buf, end, ptr, spec);
- }
- break;
- case 'a':
- {
- unsigned long long addr = *((phys_addr_t *)ptr);
- spec.flags |= SPECIAL | SMALL | ZEROPAD;
- spec.field_width = sizeof(phys_addr_t) * 2 + 2;
- spec.base = 16;
- return number(buf, end,
- kptr_restrict_cleanse_addresses() ? 0UL : addr,
- spec);
- }
- case 'P':
- /*
- * an explicitly whitelisted kernel pointer should never be
- * cleansed
- */
- break;
- default:
+ case 'K':
/*
- * plain %p, no extension, check if we should always cleanse and
- * treat like %pK.
+ * %pK cannot be used in IRQ context because its test
+ * for CAP_SYSLOG would be meaningless.
*/
- if (!kptr_restrict_always_cleanse_pointers()) {
- break;
+ if (kptr_restrict && (in_irq() || in_serving_softirq() ||
+ in_nmi())) {
+ if (spec.field_width == -1)
+ spec.field_width = default_width;
+ return string(buf, end, "pK-error", spec);
}
- /* fallthrough */
- case 'K':
+
switch (kptr_restrict) {
case 0:
- /* Always print %p values */
+ /* Always print %pK values */
break;
case 1: {
- const struct cred *cred;
-
- /*
- * kptr_restrict==1 cannot be used in IRQ context
- * because its test for CAP_SYSLOG would be meaningless.
- */
- if (in_irq() || in_serving_softirq() || in_nmi()) {
- if (spec.field_width == -1)
- spec.field_width = default_width;
- return string(buf, end, "pK-error", spec);
- }
+ /*
+ * Only print the real pointer value if the current
+ * process has CAP_SYSLOG and is running with the
+ * same credentials it started with. This is because
+ * access to files is checked at open() time, but %pK
+ * checks permission at read() time. We don't want to
+ * leak pointer values if a binary opens a file using
+ * %pK and then elevates privileges before reading it.
+ */
+ const struct cred *cred = current_cred();
- /*
- * Only print the real pointer value if the current
- * process has CAP_SYSLOG and is running with the
- * same credentials it started with. This is because
- * access to files is checked at open() time, but %p
- * checks permission at read() time. We don't want to
- * leak pointer values if a binary opens a file using
- * %pK and then elevates privileges before reading it.
- */
- cred = current_cred();
- if (!has_capability_noaudit(current, CAP_SYSLOG) ||
- !uid_eq(cred->euid, cred->uid) ||
- !gid_eq(cred->egid, cred->gid))
- ptr = NULL;
- break;
- }
- case 2: /* restrict only %pK */
- case 3: /* restrict all non-extensioned %p and %pK */
- case 4: /* restrict all non-extensioned %p, %pK, %pa*, %p[rR] */
+ if (!has_capability_noaudit(current, CAP_SYSLOG) ||
+ !uid_eq(cred->euid, cred->uid) ||
+ !gid_eq(cred->egid, cred->gid))
+ ptr = NULL;
+ break;
+ }
+ case 2:
default:
+ /* Always print 0's for %pK */
ptr = NULL;
break;
}
break;
+
+ case 'N':
+ switch (fmt[1]) {
+ case 'F':
+ return netdev_feature_string(buf, end, ptr, spec);
+ }
+ break;
+ case 'a':
+ spec.flags |= SPECIAL | SMALL | ZEROPAD;
+ spec.field_width = sizeof(phys_addr_t) * 2 + 2;
+ spec.base = 16;
+ return number(buf, end,
+ (unsigned long long) *((phys_addr_t *)ptr), spec);
}
spec.flags |= SMALL;
if (spec.field_width == -1) {
@@ -1226,7 +1170,7 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
}
spec.base = 16;
- return number(buf, end, (unsigned long long) ptr, spec);
+ return number(buf, end, (unsigned long) ptr, spec);
}
/*
diff --git a/mm/Kconfig b/mm/Kconfig
index 01da31cd07b..77beaa69c7e 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -316,16 +316,6 @@ config KSM
until a program has madvised that an area is MADV_MERGEABLE, and
root has set /sys/kernel/mm/ksm/run to 1 (if CONFIG_SYSFS is set).
-config KSM_CHECK_PAGE
- bool "Check page before scanning"
- depends on KSM
- default n
- help
- If enabled, this will check and skip if page is already scanned in
- same KSM scan cycle.
- This is useful in situation where you have parent and
- child process marking same area for KSM scanning.
-
config DEFAULT_MMAP_MIN_ADDR
int "Low address space to protect from user allocation"
depends on MMU
diff --git a/mm/ksm.c b/mm/ksm.c
index fcd989d8ed5..2df2bd1ecf3 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -301,7 +301,8 @@ static inline struct rmap_item *alloc_rmap_item(void)
{
struct rmap_item *rmap_item;
- rmap_item = kmem_cache_zalloc(rmap_item_cache, GFP_KERNEL);
+ rmap_item = kmem_cache_zalloc(rmap_item_cache, GFP_KERNEL |
+ __GFP_NORETRY | __GFP_NOWARN);
if (rmap_item)
ksm_rmap_items++;
return rmap_item;
@@ -661,9 +662,7 @@ static void remove_rmap_item_from_tree(struct rmap_item *rmap_item)
* than left over from before.
*/
age = (unsigned char)(ksm_scan.seqnr - rmap_item->address);
-#ifndef CONFIG_KSM_CHECK_PAGE
BUG_ON(age > 1);
-#endif
if (!age)
rb_erase(&rmap_item->node,
root_unstable_tree + NUMA(rmap_item->nid));
@@ -1707,31 +1706,6 @@ next_mm:
return NULL;
}
-static inline int is_page_scanned(struct page *page)
-{
-#ifdef CONFIG_KSM_CHECK_PAGE
- /* page is already marked as ksm, so this will be simple merge */
- if (PageKsm(page))
- return 0;
-
- if (ksm_scan.seqnr & 0x1) {
- /* odd cycle */
- /* clear even cycle bit */
- ClearPageKsmScan0(page);
- /* get old value and mark it scanned */
- return TestSetPageKsmScan1(page);
- } else {
- /* even cycle */
- /* clear odd cycle bit */
- ClearPageKsmScan1(page);
- /* get old value and mark it scanned */
- return TestSetPageKsmScan0(page);
- }
-#else
- return 0;
-#endif
-}
-
/**
* ksm_do_scan - the ksm scanner main worker function.
* @scan_npages - number of pages we want to scan before we return.
@@ -1746,8 +1720,7 @@ static void ksm_do_scan(unsigned int scan_npages)
rmap_item = scan_get_next_rmap_item(&page);
if (!rmap_item)
return;
- if (!is_page_scanned(page))
- cmp_and_merge_page(page, rmap_item);
+ cmp_and_merge_page(page, rmap_item);
put_page(page);
}
}
diff --git a/mm/mmap.c b/mm/mmap.c
index 9405d6f7ff8..23e0db0fc24 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2132,7 +2132,7 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address)
/* Guard against exceeding limits of the address space. */
address &= PAGE_MASK;
- if (address >= TASK_SIZE)
+ if (address >= (TASK_SIZE & PAGE_MASK))
return -ENOMEM;
address += PAGE_SIZE;
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index e8bc902eb5f..db8f3b3ca0b 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -485,7 +485,7 @@ static void writeout_period(unsigned long t)
* registered backing devices, which, for obvious reasons, can not
* exceed 100%.
*/
-static unsigned int bdi_min_ratio = 5;
+static unsigned int bdi_min_ratio;
int bdi_set_min_ratio(struct backing_dev_info *bdi, unsigned int min_ratio)
{
@@ -2399,7 +2399,7 @@ int test_clear_page_writeback(struct page *page)
return ret;
}
-int test_set_page_writeback(struct page *page)
+int __test_set_page_writeback(struct page *page, bool keep_write)
{
struct address_space *mapping = page_mapping(page);
int ret;
@@ -2421,9 +2421,10 @@ int test_set_page_writeback(struct page *page)
radix_tree_tag_clear(&mapping->page_tree,
page_index(page),
PAGECACHE_TAG_DIRTY);
- radix_tree_tag_clear(&mapping->page_tree,
- page_index(page),
- PAGECACHE_TAG_TOWRITE);
+ if (!keep_write)
+ radix_tree_tag_clear(&mapping->page_tree,
+ page_index(page),
+ PAGECACHE_TAG_TOWRITE);
spin_unlock_irqrestore(&mapping->tree_lock, flags);
} else {
ret = TestSetPageWriteback(page);
@@ -2433,7 +2434,7 @@ int test_set_page_writeback(struct page *page)
return ret;
}
-EXPORT_SYMBOL(test_set_page_writeback);
+EXPORT_SYMBOL(__test_set_page_writeback);
/*
* Return true if any of the pages in the mapping are marked with the
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 0c602215eae..bad1245ad9b 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -5345,8 +5345,8 @@ unsigned long free_reserved_area(unsigned long start, unsigned long end,
}
if (pages && s)
- pr_info("Freeing %s memory: %ldK (%lx - %lx)\n",
- s, pages << (PAGE_SHIFT - 10), start, end);
+ pr_info("Freeing %s memory: %ldK\n",
+ s, pages << (PAGE_SHIFT - 10));
return pages;
}
@@ -6475,9 +6475,6 @@ static const struct trace_print_flags pageflag_names[] = {
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
{1UL << PG_compound_lock, "compound_lock" },
#endif
-#ifdef CONFIG_KSM_CHECK_PAGE
- {1UL << PG_ksm_scan0, "PG_ksm_scan0" },
-#endif
{1UL << PG_readahead, "PG_readahead" },
};
diff --git a/mm/vmstat.c b/mm/vmstat.c
index ecb46431255..cc8ac9b1cfd 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -1244,9 +1244,7 @@ static int vmstat_show(struct seq_file *m, void *arg)
unsigned long *l = arg;
unsigned long off = l - (unsigned long *)m->private;
- seq_puts(m, vmstat_text[off]);
- seq_put_decimal_ull(m, ' ', *l);
- seq_putc(m, '\n');
+ seq_printf(m, "%s %lu\n", vmstat_text[off], *l);
return 0;
}
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 86abb2e59ae..82fdb35154f 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -274,7 +274,8 @@ static int register_vlan_device(struct net_device *real_dev, u16 vlan_id)
return 0;
out_free_newdev:
- free_netdev(new_dev);
+ if (new_dev->reg_state == NETREG_UNINITIALIZED)
+ free_netdev(new_dev);
return err;
}
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
index 13f3b1ff245..f2de0183ab2 100644
--- a/net/bluetooth/bnep/core.c
+++ b/net/bluetooth/bnep/core.c
@@ -32,6 +32,7 @@
#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/l2cap.h>
#include <net/bluetooth/hci_core.h>
#include "bnep.h"
@@ -539,6 +540,9 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
BT_DBG("");
+ if (!l2cap_is_socket(sock))
+ return -EBADFD;
+
baswap((void *) dst, &bt_sk(sock->sk)->dst);
baswap((void *) src, &bt_sk(sock->sk)->src);
diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c
index d74d9fe5411..e74d331a139 100644
--- a/net/bluetooth/cmtp/core.c
+++ b/net/bluetooth/cmtp/core.c
@@ -334,6 +334,9 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
BT_DBG("");
+ if (!l2cap_is_socket(sock))
+ return -EBADFD;
+
session = kzalloc(sizeof(struct cmtp_session), GFP_KERNEL);
if (!session)
return -ENOMEM;
diff --git a/net/core/dev.c b/net/core/dev.c
index d4e6d248dca..e8bcdeddb0d 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2342,9 +2342,10 @@ EXPORT_SYMBOL(skb_mac_gso_segment);
static inline bool skb_needs_check(struct sk_buff *skb, bool tx_path)
{
if (tx_path)
- return skb->ip_summed != CHECKSUM_PARTIAL;
- else
- return skb->ip_summed == CHECKSUM_NONE;
+ return skb->ip_summed != CHECKSUM_PARTIAL &&
+ skb->ip_summed != CHECKSUM_NONE;
+
+ return skb->ip_summed == CHECKSUM_NONE;
}
/**
@@ -2361,11 +2362,12 @@ static inline bool skb_needs_check(struct sk_buff *skb, bool tx_path)
struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
netdev_features_t features, bool tx_path)
{
+ struct sk_buff *segs;
+
if (unlikely(skb_needs_check(skb, tx_path))) {
int err;
- skb_warn_bad_offload(skb);
-
+ /* We're going to init ->check field in TCP or UDP header */
if (skb_header_cloned(skb) &&
(err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
return ERR_PTR(err);
@@ -2375,7 +2377,12 @@ struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
skb_reset_mac_header(skb);
skb_reset_mac_len(skb);
- return skb_mac_gso_segment(skb, features);
+ segs = skb_mac_gso_segment(skb, features);
+
+ if (unlikely(skb_needs_check(skb, tx_path)))
+ skb_warn_bad_offload(skb);
+
+ return segs;
}
EXPORT_SYMBOL(__skb_gso_segment);
@@ -4045,9 +4052,16 @@ static void net_rps_action_and_irq_enable(struct softnet_data *sd)
while (remsd) {
struct softnet_data *next = remsd->rps_ipi_next;
- if (cpu_online(remsd->cpu))
+ if (cpu_online(remsd->cpu)) {
__smp_call_function_single(remsd->cpu,
&remsd->csd, 0);
+ } else {
+ pr_err("%s(), cpu was offline and IPI was not "
+ "delivered so clean up NAPI", __func__);
+ rps_lock(remsd);
+ remsd->backlog.state = 0;
+ rps_unlock(remsd);
+ }
remsd = next;
}
} else
@@ -5658,7 +5672,7 @@ struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev,
} else {
netdev_stats_to_stats64(storage, &dev->stats);
}
- storage->rx_dropped += atomic_long_read(&dev->rx_dropped);
+ storage->rx_dropped += (unsigned long)atomic_long_read(&dev->rx_dropped);
return storage;
}
EXPORT_SYMBOL(dev_get_stats);
@@ -6056,6 +6070,7 @@ static int dev_cpu_callback(struct notifier_block *nfb,
if (action != CPU_DEAD && action != CPU_DEAD_FROZEN)
return NOTIFY_OK;
+
local_irq_disable();
cpu = smp_processor_id();
sd = &per_cpu(softnet_data, cpu);
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index 962e3d543aa..fb9adc5d193 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -17,10 +17,10 @@
#include <net/sock.h>
#include <net/fib_rules.h>
-static const struct fib_kuid_range fib_kuid_range_unset = {
- KUIDT_INIT(0),
- KUIDT_INIT(~0),
-};
+#define uid_valid(uid) ((uid) != -1)
+#define uid_lte(a, b) ((a) <= (b))
+#define uid_eq(a, b) ((a) == (b))
+#define uid_gte(a, b) ((a) >= (b))
int fib_default_rule_add(struct fib_rules_ops *ops,
u32 pref, u32 table, u32 flags)
@@ -36,8 +36,9 @@ int fib_default_rule_add(struct fib_rules_ops *ops,
r->pref = pref;
r->table = table;
r->flags = flags;
+ r->uid_start = INVALID_UID;
+ r->uid_end = INVALID_UID;
r->fr_net = hold_net(ops->fro_net);
- r->uid_range = fib_kuid_range_unset;
/* The lock is not required here, the list in unreacheable
* at the moment this function is called */
@@ -185,32 +186,21 @@ void fib_rules_unregister(struct fib_rules_ops *ops)
}
EXPORT_SYMBOL_GPL(fib_rules_unregister);
-static int uid_range_set(struct fib_kuid_range *range)
+static inline uid_t fib_nl_uid(struct nlattr *nla)
{
- return uid_valid(range->start) && uid_valid(range->end);
+ return nla_get_u32(nla);
}
-static struct fib_kuid_range nla_get_kuid_range(struct nlattr **tb)
+static int nla_put_uid(struct sk_buff *skb, int idx, uid_t uid)
{
- struct fib_rule_uid_range *in;
- struct fib_kuid_range out;
-
- in = (struct fib_rule_uid_range *)nla_data(tb[FRA_UID_RANGE]);
-
- out.start = make_kuid(current_user_ns(), in->start);
- out.end = make_kuid(current_user_ns(), in->end);
-
- return out;
+ return nla_put_u32(skb, idx, uid);
}
-static int nla_put_uid_range(struct sk_buff *skb, struct fib_kuid_range *range)
+static int fib_uid_range_match(struct flowi *fl, struct fib_rule *rule)
{
- struct fib_rule_uid_range out = {
- from_kuid_munged(current_user_ns(), range->start),
- from_kuid_munged(current_user_ns(), range->end)
- };
-
- return nla_put(skb, FRA_UID_RANGE, sizeof(out), &out);
+ return (!uid_valid(rule->uid_start) && !uid_valid(rule->uid_end)) ||
+ (uid_gte(fl->flowi_uid, rule->uid_start) &&
+ uid_lte(fl->flowi_uid, rule->uid_end));
}
static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops,
@@ -227,8 +217,7 @@ static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops,
if ((rule->mark ^ fl->flowi_mark) & rule->mark_mask)
goto out;
- if (uid_lt(fl->flowi_uid, rule->uid_range.start) ||
- uid_gt(fl->flowi_uid, rule->uid_range.end))
+ if (!fib_uid_range_match(fl, rule))
goto out;
ret = ops->match(rule, fl, flags);
@@ -401,19 +390,17 @@ static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh)
} else if (rule->action == FR_ACT_GOTO)
goto errout_free;
- if (tb[FRA_UID_RANGE]) {
- if (current_user_ns() != net->user_ns) {
- err = -EPERM;
- goto errout_free;
+ /* UID start and end must either both be valid or both unspecified. */
+ rule->uid_start = rule->uid_end = INVALID_UID;
+ if (tb[FRA_UID_START] || tb[FRA_UID_END]) {
+ if (tb[FRA_UID_START] && tb[FRA_UID_END]) {
+ rule->uid_start = fib_nl_uid(tb[FRA_UID_START]);
+ rule->uid_end = fib_nl_uid(tb[FRA_UID_END]);
}
-
- rule->uid_range = nla_get_kuid_range(tb);
-
- if (!uid_range_set(&rule->uid_range) ||
- !uid_lte(rule->uid_range.start, rule->uid_range.end))
- goto errout_free;
- } else {
- rule->uid_range = fib_kuid_range_unset;
+ if (!uid_valid(rule->uid_start) ||
+ !uid_valid(rule->uid_end) ||
+ !uid_lte(rule->uid_start, rule->uid_end))
+ goto errout_free;
}
err = ops->configure(rule, skb, frh, tb);
@@ -475,7 +462,6 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh)
struct fib_rules_ops *ops = NULL;
struct fib_rule *rule, *tmp;
struct nlattr *tb[FRA_MAX+1];
- struct fib_kuid_range range;
int err = -EINVAL;
if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*frh)))
@@ -495,14 +481,6 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh)
if (err < 0)
goto errout;
- if (tb[FRA_UID_RANGE]) {
- range = nla_get_kuid_range(tb);
- if (!uid_range_set(&range))
- goto errout;
- } else {
- range = fib_kuid_range_unset;
- }
-
list_for_each_entry(rule, &ops->rules_list, list) {
if (frh->action && (frh->action != rule->action))
continue;
@@ -531,9 +509,12 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh)
(rule->mark_mask != nla_get_u32(tb[FRA_FWMASK])))
continue;
- if (uid_range_set(&range) &&
- (!uid_eq(rule->uid_range.start, range.start) ||
- !uid_eq(rule->uid_range.end, range.end)))
+ if (tb[FRA_UID_START] &&
+ !uid_eq(rule->uid_start, fib_nl_uid(tb[FRA_UID_START])))
+ continue;
+
+ if (tb[FRA_UID_END] &&
+ !uid_eq(rule->uid_end, fib_nl_uid(tb[FRA_UID_END])))
continue;
if (!ops->compare(rule, frh, tb))
@@ -593,7 +574,8 @@ static inline size_t fib_rule_nlmsg_size(struct fib_rules_ops *ops,
+ nla_total_size(4) /* FRA_TABLE */
+ nla_total_size(4) /* FRA_FWMARK */
+ nla_total_size(4) /* FRA_FWMASK */
- + nla_total_size(sizeof(struct fib_kuid_range));
+ + nla_total_size(4) /* FRA_UID_START */
+ + nla_total_size(4); /* FRA_UID_END */
if (ops->nlmsg_payload)
payload += ops->nlmsg_payload(rule);
@@ -647,10 +629,15 @@ static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule,
((rule->mark_mask || rule->mark) &&
nla_put_u32(skb, FRA_FWMASK, rule->mark_mask)) ||
(rule->target &&
- nla_put_u32(skb, FRA_GOTO, rule->target)) ||
- (uid_range_set(&rule->uid_range) &&
- nla_put_uid_range(skb, &rule->uid_range)))
+ nla_put_u32(skb, FRA_GOTO, rule->target)))
goto nla_put_failure;
+
+ if (uid_valid(rule->uid_start))
+ nla_put_uid(skb, FRA_UID_START, rule->uid_start);
+
+ if (uid_valid(rule->uid_end))
+ nla_put_uid(skb, FRA_UID_END, rule->uid_end);
+
if (ops->fill(rule, skb, frh) < 0)
goto nla_put_failure;
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 0c5602cf263..b678920f4b9 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -827,7 +827,7 @@ out:
* ARP entry timeouts range from 1/2 base_reachable_time to 3/2
* base_reachable_time.
*/
- queue_delayed_work(system_power_efficient_wq, &tbl->gc_work,
+ schedule_delayed_work(&tbl->gc_work,
tbl->parms.base_reachable_time >> 1);
write_unlock_bh(&tbl->lock);
}
@@ -1561,8 +1561,7 @@ static void neigh_table_init_no_netlink(struct neigh_table *tbl)
rwlock_init(&tbl->lock);
INIT_DEFERRABLE_WORK(&tbl->gc_work, neigh_periodic_work);
- queue_delayed_work(system_power_efficient_wq, &tbl->gc_work,
- tbl->parms.reachable_time);
+ schedule_delayed_work(&tbl->gc_work, tbl->parms.reachable_time);
setup_timer(&tbl->proxy_timer, neigh_proxy_process, (unsigned long)tbl);
skb_queue_head_init_class(&tbl->proxy_queue,
&neigh_table_proxy_queue_class);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 602c6d0492e..c468470112a 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -899,8 +899,14 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
goto nla_put_failure;
if (1) {
- struct rtnl_link_ifmap map;
-
+ struct rtnl_link_ifmap map = {
+ .mem_start = dev->mem_start,
+ .mem_end = dev->mem_end,
+ .base_addr = dev->base_addr,
+ .irq = dev->irq,
+ .dma = dev->dma,
+ .port = dev->if_port,
+ };
memset(&map, 0, sizeof(map));
map.mem_start = dev->mem_start;
map.mem_end = dev->mem_end;
diff --git a/net/core/sock.c b/net/core/sock.c
index 09bb754627e..62a983dd651 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1470,6 +1470,8 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
sock_copy(newsk, sk);
+ newsk->sk_prot_creator = sk->sk_prot;
+
/* SANITY */
get_net(sock_net(newsk));
sk_node_init(&newsk->sk_node);
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index c02311f22eb..0438209b294 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1075,7 +1075,7 @@ static struct inet_protosw inetsw_array[] =
.type = SOCK_DGRAM,
.protocol = IPPROTO_ICMP,
.prot = &ping_prot,
- .ops = &inet_dgram_ops,
+ .ops = &inet_sockraw_ops,
.no_check = UDP_CSUM_DEFAULT,
.flags = INET_PROTOSW_REUSE,
},
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 5b85c29d7d9..b151e0ac7f2 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -469,7 +469,7 @@ static int __inet_insert_ifa(struct in_ifaddr *ifa, struct nlmsghdr *nlh,
inet_hash_insert(dev_net(in_dev->dev), ifa);
cancel_delayed_work(&check_lifetime_work);
- queue_delayed_work(system_power_efficient_wq, &check_lifetime_work, 0);
+ schedule_delayed_work(&check_lifetime_work, 0);
/* Send message first, then call notifier.
Notifier will trigger FIB update, so that
@@ -678,8 +678,7 @@ static void check_lifetime(struct work_struct *work)
if (time_before(next_sched, now + ADDRCONF_TIMER_FUZZ_MAX))
next_sched = now + ADDRCONF_TIMER_FUZZ_MAX;
- queue_delayed_work(system_power_efficient_wq, &check_lifetime_work,
- next_sched - now);
+ schedule_delayed_work(&check_lifetime_work, next_sched - now);
}
static void set_ifa_lifetime(struct in_ifaddr *ifa, __u32 valid_lft,
@@ -835,8 +834,7 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
ifa = ifa_existing;
set_ifa_lifetime(ifa, valid_lft, prefered_lft);
cancel_delayed_work(&check_lifetime_work);
- queue_delayed_work(system_power_efficient_wq,
- &check_lifetime_work, 0);
+ schedule_delayed_work(&check_lifetime_work, 0);
rtmsg_ifa(RTM_NEWADDR, ifa, nlh, NETLINK_CB(skb).portid);
blocking_notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa);
}
@@ -2301,7 +2299,7 @@ void __init devinet_init(void)
register_gifconf(PF_INET, inet_gifconf);
register_netdevice_notifier(&ip_netdev_notifier);
- queue_delayed_work(system_power_efficient_wq, &check_lifetime_work, 0);
+ schedule_delayed_work(&check_lifetime_work, 0);
rtnl_af_register(&inet_af_ops);
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index fdd555129fa..42da0b216bb 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -1171,13 +1171,14 @@ static struct pernet_operations fib_net_ops = {
void __init ip_fib_init(void)
{
- rtnl_register(PF_INET, RTM_NEWROUTE, inet_rtm_newroute, NULL, NULL);
- rtnl_register(PF_INET, RTM_DELROUTE, inet_rtm_delroute, NULL, NULL);
- rtnl_register(PF_INET, RTM_GETROUTE, NULL, inet_dump_fib, NULL);
+ fib_trie_init();
register_pernet_subsys(&fib_net_ops);
+
register_netdevice_notifier(&fib_netdev_notifier);
register_inetaddr_notifier(&fib_inetaddr_notifier);
- fib_trie_init();
+ rtnl_register(PF_INET, RTM_NEWROUTE, inet_rtm_newroute, NULL, NULL);
+ rtnl_register(PF_INET, RTM_DELROUTE, inet_rtm_delroute, NULL, NULL);
+ rtnl_register(PF_INET, RTM_GETROUTE, NULL, inet_dump_fib, NULL);
}
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 59e63dcb80d..5af8781b65e 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -364,7 +364,6 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
fl4.daddr = daddr;
fl4.saddr = saddr;
fl4.flowi4_mark = mark;
- fl4.flowi4_uid = sock_net_uid(net, NULL);
fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos);
fl4.flowi4_proto = IPPROTO_ICMP;
security_skb_classify_flow(skb, flowi4_to_flowi(&fl4));
@@ -396,7 +395,6 @@ static struct rtable *icmp_route_lookup(struct net *net,
param->replyopts.opt.opt.faddr : iph->saddr);
fl4->saddr = saddr;
fl4->flowi4_mark = mark;
- fl4->flowi4_uid = sock_net_uid(net, NULL);
fl4->flowi4_tos = RT_TOS(tos);
fl4->flowi4_proto = IPPROTO_ICMP;
fl4->fl4_icmp_type = type;
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 912cb4dedfe..008b52bc99a 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -430,7 +430,7 @@ struct dst_entry *inet_csk_route_req(struct sock *sk,
flags,
(opt && opt->opt.srr) ? opt->opt.faddr : ireq->rmt_addr,
ireq->loc_addr, ireq->rmt_port, inet_sk(sk)->inet_sport,
- sk->sk_uid);
+ sock_i_uid(sk));
security_req_classify_flow(req, flowi4_to_flowi(fl4));
rt = ip_route_output_flow(net, fl4, sk);
if (IS_ERR(rt))
@@ -467,7 +467,7 @@ struct dst_entry *inet_csk_route_child_sock(struct sock *sk,
sk->sk_protocol, inet_sk_flowi_flags(sk),
(opt && opt->opt.srr) ? opt->opt.faddr : ireq->rmt_addr,
ireq->loc_addr, ireq->rmt_port, inet_sk(sk)->inet_sport,
- sk->sk_uid);
+ sock_i_uid(sk));
security_req_classify_flow(req, flowi4_to_flowi(fl4));
rt = ip_route_output_flow(net, fl4, sk);
if (IS_ERR(rt))
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 650873c3240..1204570dcce 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -846,10 +846,12 @@ static int __ip_append_data(struct sock *sk,
csummode = CHECKSUM_PARTIAL;
cork->length += length;
- if (((length > mtu) || (skb && skb_has_frags(skb))) &&
+ if ((skb && skb_has_frags(skb)) ||
+ ((length > mtu) &&
+ (skb_queue_len(queue) <= 1) &&
(sk->sk_protocol == IPPROTO_UDP) &&
(rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len &&
- (sk->sk_type == SOCK_DGRAM)) {
+ (sk->sk_type == SOCK_DGRAM))) {
err = ip_ufo_append_data(sk, queue, getfrag, from, length,
hh_len, fragheaderlen, transhdrlen,
maxfraglen, flags);
@@ -1160,6 +1162,7 @@ ssize_t ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page,
cork->length += size;
if ((size + skb->len > mtu) &&
+ (skb_queue_len(&sk->sk_write_queue) == 1) &&
(sk->sk_protocol == IPPROTO_UDP) &&
(rt->dst.dev->features & NETIF_F_UFO)) {
skb_shinfo(skb)->gso_size = mtu - fragheaderlen;
diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c
index 5f011cc89cd..1e82bdb0f07 100644
--- a/net/ipv4/netfilter/nf_nat_snmp_basic.c
+++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c
@@ -1305,6 +1305,7 @@ static int __init nf_nat_snmp_basic_init(void)
static void __exit nf_nat_snmp_basic_fini(void)
{
RCU_INIT_POINTER(nf_nat_snmp_hook, NULL);
+ synchronize_rcu();
nf_conntrack_helper_unregister(&snmp_trap_helper);
}
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index 99bc6f5cee7..8e4f27332d6 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -785,7 +785,7 @@ int ping_v4_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos,
RT_SCOPE_UNIVERSE, sk->sk_protocol,
inet_sk_flowi_flags(sk), faddr, saddr, 0, 0,
- sk->sk_uid);
+ sock_i_uid(sk));
security_sk_classify_flow(sk, flowi4_to_flowi(&fl4));
rt = ip_route_output_flow(net, &fl4, sk);
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index c9b79f48193..b9c87c8c0b1 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -573,7 +573,8 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol,
inet_sk_flowi_flags(sk) | FLOWI_FLAG_CAN_SLEEP |
(inet->hdrincl ? FLOWI_FLAG_KNOWN_NH : 0),
- daddr, saddr, 0, 0, sk->sk_uid);
+ daddr, saddr, 0, 0,
+ sock_i_uid(sk));
if (!inet->hdrincl) {
err = raw_probe_proto_opt(&fl4, msg);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 4f3c789cb77..3283060a8cc 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -515,8 +515,7 @@ void __ip_select_ident(struct iphdr *iph, int segs)
}
EXPORT_SYMBOL(__ip_select_ident);
-static void __build_flow_key(const struct net *net, struct flowi4 *fl4,
- const struct sock *sk,
+static void __build_flow_key(struct flowi4 *fl4, struct sock *sk,
const struct iphdr *iph,
int oif, u8 tos,
u8 prot, u32 mark, int flow_flags)
@@ -533,23 +532,22 @@ static void __build_flow_key(const struct net *net, struct flowi4 *fl4,
RT_SCOPE_UNIVERSE, prot,
flow_flags,
iph->daddr, iph->saddr, 0, 0,
- sock_net_uid(net, sk));
+ sk ? sock_i_uid(sk) : 0);
}
static void build_skb_flow_key(struct flowi4 *fl4, const struct sk_buff *skb,
- const struct sock *sk)
+ struct sock *sk)
{
- const struct net *net = dev_net(skb->dev);
const struct iphdr *iph = ip_hdr(skb);
int oif = skb->dev->ifindex;
u8 tos = RT_TOS(iph->tos);
u8 prot = iph->protocol;
u32 mark = skb->mark;
- __build_flow_key(net, fl4, sk, iph, oif, tos, prot, mark, 0);
+ __build_flow_key(fl4, sk, iph, oif, tos, prot, mark, 0);
}
-static void build_sk_flow_key(struct flowi4 *fl4, const struct sock *sk)
+static void build_sk_flow_key(struct flowi4 *fl4, struct sock *sk)
{
const struct inet_sock *inet = inet_sk(sk);
const struct ip_options_rcu *inet_opt;
@@ -563,11 +561,11 @@ static void build_sk_flow_key(struct flowi4 *fl4, const struct sock *sk)
RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE,
inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol,
inet_sk_flowi_flags(sk),
- daddr, inet->inet_saddr, 0, 0, sk->sk_uid);
+ daddr, inet->inet_saddr, 0, 0, sock_i_uid(sk));
rcu_read_unlock();
}
-static void ip_rt_build_flow_key(struct flowi4 *fl4, const struct sock *sk,
+static void ip_rt_build_flow_key(struct flowi4 *fl4, struct sock *sk,
const struct sk_buff *skb)
{
if (skb)
@@ -765,7 +763,7 @@ static void ip_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_buf
rt = (struct rtable *) dst;
- __build_flow_key(sock_net(sk), &fl4, sk, iph, oif, tos, prot, mark, 0);
+ __build_flow_key(&fl4, sk, iph, oif, tos, prot, mark, 0);
__ip_do_redirect(rt, skb, &fl4, true);
}
@@ -983,7 +981,7 @@ void ipv4_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu,
if (!mark)
mark = IP4_REPLY_MARK(net, skb->mark);
- __build_flow_key(net, &fl4, NULL, iph, oif,
+ __build_flow_key(&fl4, NULL, iph, oif,
RT_TOS(iph->tos), protocol, mark, flow_flags);
rt = __ip_route_output_key(net, &fl4);
if (!IS_ERR(rt)) {
@@ -999,7 +997,7 @@ static void __ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu)
struct flowi4 fl4;
struct rtable *rt;
- __build_flow_key(sock_net(sk), &fl4, sk, iph, 0, 0, 0, 0, 0);
+ __build_flow_key(&fl4, sk, iph, 0, 0, 0, 0, 0);
if (!fl4.flowi4_mark)
fl4.flowi4_mark = IP4_REPLY_MARK(sock_net(sk), skb->mark);
@@ -1018,7 +1016,6 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu)
struct rtable *rt;
struct dst_entry *odst = NULL;
bool new = false;
- struct net *net = sock_net(sk);
bh_lock_sock(sk);
odst = sk_dst_get(sk);
@@ -1028,7 +1025,7 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu)
goto out;
}
- __build_flow_key(net, &fl4, sk, iph, 0, 0, 0, 0, 0);
+ __build_flow_key(&fl4, sk, iph, 0, 0, 0, 0, 0);
rt = (struct rtable *)odst;
if (odst->obsolete && odst->ops->check(odst, 0) == NULL) {
@@ -1068,7 +1065,7 @@ void ipv4_redirect(struct sk_buff *skb, struct net *net,
struct flowi4 fl4;
struct rtable *rt;
- __build_flow_key(net, &fl4, NULL, iph, oif,
+ __build_flow_key(&fl4, NULL, iph, oif,
RT_TOS(iph->tos), protocol, mark, flow_flags);
rt = __ip_route_output_key(net, &fl4);
if (!IS_ERR(rt)) {
@@ -1083,10 +1080,9 @@ void ipv4_sk_redirect(struct sk_buff *skb, struct sock *sk)
const struct iphdr *iph = (const struct iphdr *) skb->data;
struct flowi4 fl4;
struct rtable *rt;
- struct net *net = sock_net(sk);
- __build_flow_key(net, &fl4, sk, iph, 0, 0, 0, 0, 0);
- rt = __ip_route_output_key(net, &fl4);
+ __build_flow_key(&fl4, sk, iph, 0, 0, 0, 0, 0);
+ rt = __ip_route_output_key(sock_net(sk), &fl4);
if (!IS_ERR(rt)) {
__ip_do_redirect(rt, skb, &fl4, false);
ip_rt_put(rt);
@@ -1161,6 +1157,7 @@ void ip_rt_get_source(u8 *addr, struct sk_buff *skb, struct rtable *rt)
fl4.flowi4_oif = rt->dst.dev->ifindex;
fl4.flowi4_iif = skb->dev->ifindex;
fl4.flowi4_mark = skb->mark;
+ fl4.flowi4_uid = skb->sk ? sock_i_uid(skb->sk) : 0;
rcu_read_lock();
if (fib_lookup(dev_net(rt->dst.dev), &fl4, &res) == 0)
@@ -1451,6 +1448,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
rth->rt_iif = 0;
rth->rt_pmtu = 0;
rth->rt_gateway = 0;
+ rth->rt_uid = 0;
rth->rt_uses_gateway = 0;
INIT_LIST_HEAD(&rth->rt_uncached);
if (our) {
@@ -1574,6 +1572,7 @@ static int __mkroute_input(struct sk_buff *skb,
rth->rt_is_input = 1;
rth->rt_iif = 0;
rth->rt_pmtu = 0;
+ rth->rt_uid = 0;
rth->rt_gateway = 0;
rth->rt_uses_gateway = 0;
INIT_LIST_HEAD(&rth->rt_uncached);
@@ -1744,6 +1743,7 @@ local_input:
rth->rt_is_input = 1;
rth->rt_iif = 0;
rth->rt_pmtu = 0;
+ rth->rt_uid = 0;
rth->rt_gateway = 0;
rth->rt_uses_gateway = 0;
INIT_LIST_HEAD(&rth->rt_uncached);
@@ -1947,6 +1947,7 @@ add:
rth->rt_is_input = 0;
rth->rt_iif = orig_oif ? : 0;
rth->rt_pmtu = 0;
+ rth->rt_uid = fl4->flowi4_uid;
rth->rt_gateway = 0;
rth->rt_uses_gateway = 0;
INIT_LIST_HEAD(&rth->rt_uncached);
@@ -2222,6 +2223,7 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or
rt->rt_is_input = ort->rt_is_input;
rt->rt_iif = ort->rt_iif;
rt->rt_pmtu = ort->rt_pmtu;
+ rt->rt_uid = ort->rt_uid;
rt->rt_genid = rt_genid(net);
rt->rt_flags = ort->rt_flags;
@@ -2332,9 +2334,8 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src,
nla_put_u32(skb, RTA_MARK, fl4->flowi4_mark))
goto nla_put_failure;
- if (!uid_eq(fl4->flowi4_uid, INVALID_UID) &&
- nla_put_u32(skb, RTA_UID,
- from_kuid_munged(current_user_ns(), fl4->flowi4_uid)))
+ if (rt->rt_uid != (uid_t) -1 &&
+ nla_put_u32(skb, RTA_UID, rt->rt_uid))
goto nla_put_failure;
error = rt->dst.error;
@@ -2387,7 +2388,6 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh)
int err;
int mark;
struct sk_buff *skb;
- kuid_t uid;
err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv4_policy);
if (err < 0)
@@ -2415,10 +2415,6 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh)
dst = tb[RTA_DST] ? nla_get_be32(tb[RTA_DST]) : 0;
iif = tb[RTA_IIF] ? nla_get_u32(tb[RTA_IIF]) : 0;
mark = tb[RTA_MARK] ? nla_get_u32(tb[RTA_MARK]) : 0;
- if (tb[RTA_UID])
- uid = make_kuid(current_user_ns(), nla_get_u32(tb[RTA_UID]));
- else
- uid = (iif ? INVALID_UID : current_uid());
memset(&fl4, 0, sizeof(fl4));
fl4.daddr = dst;
@@ -2426,7 +2422,6 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh)
fl4.flowi4_tos = rtm->rtm_tos;
fl4.flowi4_oif = tb[RTA_OIF] ? nla_get_u32(tb[RTA_OIF]) : 0;
fl4.flowi4_mark = mark;
- fl4.flowi4_uid = uid;
if (iif) {
struct net_device *dev;
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index 296a0a42b2b..c94032b95c6 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -353,7 +353,8 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, IPPROTO_TCP,
inet_sk_flowi_flags(sk),
(opt && opt->srr) ? opt->faddr : ireq->rmt_addr,
- ireq->loc_addr, th->source, th->dest, sk->sk_uid);
+ ireq->loc_addr, th->source, th->dest,
+ sock_i_uid(sk));
security_req_classify_flow(req, flowi4_to_flowi(&fl4));
rt = ip_route_output_key(sock_net(sk), &fl4);
if (IS_ERR(rt)) {
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index e813bc8c7cd..95de798afcb 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2336,9 +2336,15 @@ int tcp_disconnect(struct sock *sk, int flags)
tcp_set_ca_state(sk, TCP_CA_Open);
tcp_clear_retrans(tp);
inet_csk_delack_init(sk);
+ /* Initialize rcv_mss to TCP_MIN_MSS to avoid division by 0
+ * issue in __tcp_select_window()
+ */
+ icsk->icsk_ack.rcv_mss = TCP_MIN_MSS;
tcp_init_send_head(sk);
memset(&tp->rx_opt, 0, sizeof(tp->rx_opt));
__sk_dst_reset(sk);
+ dst_release(sk->sk_rx_dst);
+ sk->sk_rx_dst = NULL;
WARN_ON(inet->inet_num && !icsk->icsk_bind_hash);
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c
index 019c2389a34..2ca6c080a4b 100644
--- a/net/ipv4/tcp_cong.c
+++ b/net/ipv4/tcp_cong.c
@@ -95,6 +95,7 @@ void tcp_init_congestion_control(struct sock *sk)
rcu_read_unlock();
}
+ tcp_sk(sk)->prior_ssthresh = 0;
if (icsk->icsk_ca_ops->init)
icsk->icsk_ca_ops->init(sk);
}
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index e3ec3ecb4bd..f7513458ea9 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -112,6 +112,7 @@ int sysctl_tcp_default_init_rwnd __read_mostly = TCP_DEFAULT_INIT_RCVWND;
#define FLAG_ORIG_SACK_ACKED 0x200 /* Never retransmitted data are (s)acked */
#define FLAG_SND_UNA_ADVANCED 0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */
#define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained D-SACK info */
+#define FLAG_SET_XMIT_TIMER 0x1000 /* Set TLP or RTO timer */
#define FLAG_SACK_RENEGING 0x2000 /* snd_una advanced to a sacked seq */
#define FLAG_UPDATE_TS_RECENT 0x4000 /* tcp_replace_ts_recent() */
@@ -2554,8 +2555,8 @@ static inline void tcp_end_cwnd_reduction(struct sock *sk)
struct tcp_sock *tp = tcp_sk(sk);
/* Reset cwnd to ssthresh in CWR or Recovery (unless it's undone) */
- if (inet_csk(sk)->icsk_ca_state == TCP_CA_CWR ||
- (tp->undo_marker && tp->snd_ssthresh < TCP_INFINITE_SSTHRESH)) {
+ if (tp->snd_ssthresh < TCP_INFINITE_SSTHRESH &&
+ (inet_csk(sk)->icsk_ca_state == TCP_CA_CWR || tp->undo_marker)) {
tp->snd_cwnd = tp->snd_ssthresh;
tp->snd_cwnd_stamp = tcp_time_stamp;
}
@@ -2973,14 +2974,11 @@ void tcp_rearm_rto(struct sock *sk)
/* Offset the time elapsed after installing regular RTO */
if (icsk->icsk_pending == ICSK_TIME_EARLY_RETRANS ||
icsk->icsk_pending == ICSK_TIME_LOSS_PROBE) {
- struct sk_buff *skb = tcp_write_queue_head(sk);
- const u32 rto_time_stamp = TCP_SKB_CB(skb)->when + rto;
- s32 delta = (s32)(rto_time_stamp - tcp_time_stamp);
+ s32 delta = tcp_rto_delta(sk);
/* delta may not be positive if the socket is locked
* when the retrans timer fires and is rescheduled.
*/
- if (delta > 0)
- rto = delta;
+ rto = max_t(int, delta, 1);
}
inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, rto,
TCP_RTO_MAX);
@@ -3005,6 +3003,13 @@ void tcp_resume_early_retransmit(struct sock *sk)
tcp_xmit_retransmit_queue(sk);
}
+/* Try to schedule a loss probe; if that doesn't work, then schedule an RTO. */
+static void tcp_set_xmit_timer(struct sock *sk)
+{
+ if (!tcp_schedule_loss_probe(sk))
+ tcp_rearm_rto(sk);
+}
+
/* If we get here, the whole TSO packet has not been acked. */
static u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb)
{
@@ -3135,7 +3140,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets,
}
tcp_ack_update_rtt(sk, flag, seq_rtt);
- tcp_rearm_rto(sk);
+ flag |= FLAG_SET_XMIT_TIMER; /* set TLP or RTO timer */
if (tcp_is_reno(tp)) {
tcp_remove_reno_sacks(sk, pkts_acked);
@@ -3395,10 +3400,6 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
if (after(ack, tp->snd_nxt))
goto invalid_ack;
- if (icsk->icsk_pending == ICSK_TIME_EARLY_RETRANS ||
- icsk->icsk_pending == ICSK_TIME_LOSS_PROBE)
- tcp_rearm_rto(sk);
-
if (after(ack, prior_snd_una))
flag |= FLAG_SND_UNA_ADVANCED;
@@ -3455,6 +3456,12 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
pkts_acked = previous_packets_out - tp->packets_out;
+ if (tp->tlp_high_seq)
+ tcp_process_tlp_ack(sk, ack, flag);
+ /* If needed, reset TLP/RTO timer; RACK may later override this. */
+ if (flag & FLAG_SET_XMIT_TIMER)
+ tcp_set_xmit_timer(sk);
+
if (tcp_ack_is_dubious(sk, flag)) {
/* Advance CWND, if state allows this. */
if ((flag & FLAG_DATA_ACKED) && tcp_may_raise_cwnd(sk, flag))
@@ -3467,17 +3474,12 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
tcp_cong_avoid(sk, ack, prior_in_flight);
}
- if (tp->tlp_high_seq)
- tcp_process_tlp_ack(sk, ack, flag);
-
if ((flag & FLAG_FORWARD_PROGRESS) || !(flag & FLAG_NOT_DUP)) {
struct dst_entry *dst = __sk_dst_get(sk);
if (dst)
dst_confirm(dst);
}
- if (icsk->icsk_pending == ICSK_TIME_RETRANS)
- tcp_schedule_loss_probe(sk);
if (tp->srtt != prior_rtt || tp->snd_cwnd != prior_cwnd)
tcp_update_pacing_rate(sk);
return 1;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 7e3ae5513fb..4c5724f6fd1 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -711,7 +711,6 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
arg.bound_dev_if = sk->sk_bound_dev_if;
arg.tos = ip_hdr(skb)->tos;
- arg.uid = sock_net_uid(net, sk && sk_fullsock(sk) ? sk : NULL);
ip_send_unicast_reply(*this_cpu_ptr(net->ipv4.tcp_sk),
skb, ip_hdr(skb)->saddr,
ip_hdr(skb)->daddr, &arg, arg.iov[0].iov_len);
@@ -732,8 +731,7 @@ release_sk1:
outside socket context is ugly, certainly. What can I do?
*/
-static void tcp_v4_send_ack(const struct sock *sk, struct sk_buff *skb,
- u32 seq, u32 ack,
+static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
u32 win, u32 tsval, u32 tsecr, int oif,
struct tcp_md5sig_key *key,
int reply_flags, u8 tos)
@@ -748,7 +746,7 @@ static void tcp_v4_send_ack(const struct sock *sk, struct sk_buff *skb,
];
} rep;
struct ip_reply_arg arg;
- struct net *net = sock_net(sk);
+ struct net *net = dev_net(skb_dst(skb)->dev);
memset(&rep.th, 0, sizeof(struct tcphdr));
memset(&arg, 0, sizeof(arg));
@@ -797,7 +795,6 @@ static void tcp_v4_send_ack(const struct sock *sk, struct sk_buff *skb,
if (oif)
arg.bound_dev_if = oif;
arg.tos = tos;
- arg.uid = sock_net_uid(net, sk_fullsock(sk) ? sk : NULL);
ip_send_unicast_reply(*this_cpu_ptr(net->ipv4.tcp_sk),
skb, ip_hdr(skb)->saddr,
ip_hdr(skb)->daddr, &arg, arg.iov[0].iov_len);
@@ -810,7 +807,7 @@ static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb)
struct inet_timewait_sock *tw = inet_twsk(sk);
struct tcp_timewait_sock *tcptw = tcp_twsk(sk);
- tcp_v4_send_ack(sk, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
+ tcp_v4_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
tcp_time_stamp + tcptw->tw_ts_offset,
tcptw->tw_ts_recent,
@@ -829,10 +826,9 @@ static void tcp_v4_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
/* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV
* sk->sk_state == TCP_SYN_RECV -> for Fast Open.
*/
- tcp_v4_send_ack(sk, skb, (sk->sk_state == TCP_LISTEN) ?
+ tcp_v4_send_ack(skb, (sk->sk_state == TCP_LISTEN) ?
tcp_rsk(req)->snt_isn + 1 : tcp_sk(sk)->snd_nxt,
- tcp_rsk(req)->rcv_nxt,
- req->rcv_wnd >> inet_rsk(req)->rcv_wscale,
+ tcp_rsk(req)->rcv_nxt, req->rcv_wnd,
tcp_time_stamp,
req->ts_recent,
0,
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 9c3fc860d2b..4b41fac4a0a 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -247,12 +247,6 @@ void tcp_select_initial_window(int __space, __u32 mss,
else
*rcv_wnd = min(*rcv_wnd, init_cwnd * mss);
}
-
- /* Lock the initial TCP window size to 64K*/
- *rcv_wnd = 64240;
-
- /* Lock the initial TCP window size to 64K*/
- *rcv_wnd = 64240;
/* Set the clamp no higher than max representable value */
(*window_clamp) = min(65535U << (*rcv_wscale), *window_clamp);
@@ -1948,28 +1942,16 @@ repair:
bool tcp_schedule_loss_probe(struct sock *sk)
{
- struct inet_connection_sock *icsk = inet_csk(sk);
struct tcp_sock *tp = tcp_sk(sk);
- u32 timeout, tlp_time_stamp, rto_time_stamp;
u32 rtt = tp->srtt >> 3;
+ u32 timeout, rto_delta;
- if (WARN_ON(icsk->icsk_pending == ICSK_TIME_EARLY_RETRANS))
- return false;
- /* No consecutive loss probes. */
- if (WARN_ON(icsk->icsk_pending == ICSK_TIME_LOSS_PROBE)) {
- tcp_rearm_rto(sk);
- return false;
- }
/* Don't do any loss probe on a Fast Open connection before 3WHS
* finishes.
*/
if (sk->sk_state == TCP_SYN_RECV)
return false;
- /* TLP is only scheduled when next timer event is RTO. */
- if (icsk->icsk_pending != ICSK_TIME_RETRANS)
- return false;
-
/* Schedule a loss probe in 2*RTT for SACK capable connections
* in Open state, that are either limited by cwnd or application.
*/
@@ -1990,14 +1972,10 @@ bool tcp_schedule_loss_probe(struct sock *sk)
(rtt + (rtt >> 1) + TCP_DELACK_MAX));
timeout = max_t(u32, timeout, msecs_to_jiffies(10));
- /* If RTO is shorter, just schedule TLP in its place. */
- tlp_time_stamp = tcp_time_stamp + timeout;
- rto_time_stamp = (u32)inet_csk(sk)->icsk_timeout;
- if ((s32)(tlp_time_stamp - rto_time_stamp) > 0) {
- s32 delta = rto_time_stamp - tcp_time_stamp;
- if (delta > 0)
- timeout = delta;
- }
+ /* If the RTO formula yields an earlier time, then use that time. */
+ rto_delta = tcp_rto_delta(sk); /* How far in future is RTO? */
+ if (rto_delta > 0)
+ timeout = min_t(u32, timeout, rto_delta);
inet_csk_reset_xmit_timer(sk, ICSK_TIME_LOSS_PROBE, timeout,
TCP_RTO_MAX);
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 333dcb2f5e6..959145f9a8d 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -769,7 +769,7 @@ static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4)
if (is_udplite) /* UDP-Lite */
csum = udplite_csum(skb);
- else if (sk->sk_no_check == UDP_CSUM_NOXMIT) { /* UDP csum disabled */
+ else if (sk->sk_no_check == UDP_CSUM_NOXMIT && !skb_has_frags(skb)) { /* UDP csum off */
skb->ip_summed = CHECKSUM_NONE;
goto send;
@@ -970,7 +970,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
RT_SCOPE_UNIVERSE, sk->sk_protocol,
inet_sk_flowi_flags(sk)|FLOWI_FLAG_CAN_SLEEP,
faddr, saddr, dport, inet->inet_sport,
- sk->sk_uid);
+ sock_i_uid(sk));
security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
rt = ip_route_output_flow(net, fl4, sk);
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 9b5b5ddf8cd..4c436751bf9 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -80,6 +80,7 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
const struct flowi4 *fl4 = &fl->u.ip4;
xdst->u.rt.rt_iif = fl4->flowi4_iif;
+ xdst->u.rt.rt_uid = fl4->flowi4_uid;
xdst->u.dst.dev = dev;
dev_hold(dev);
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 81958340133..c1119609e2a 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2969,6 +2969,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
{
struct net_device *dev = (struct net_device *) data;
struct inet6_dev *idev = __in6_dev_get(dev);
+ struct net *net = dev_net(dev);
int run_pending = 0;
int err;
@@ -3065,7 +3066,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
* IPV6_MIN_MTU stop IPv6 on this interface.
*/
if (dev->mtu < IPV6_MIN_MTU)
- addrconf_ifdown(dev, 1);
+ addrconf_ifdown(dev, dev != net->loopback_dev);
}
break;
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 3d90a43e641..4656cb363c5 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -699,7 +699,7 @@ int inet6_sk_rebuild_header(struct sock *sk)
fl6.flowi6_mark = sk->sk_mark;
fl6.fl6_dport = inet->inet_dport;
fl6.fl6_sport = inet->inet_sport;
- fl6.flowi6_uid = sk->sk_uid;
+ fl6.flowi6_uid = sock_i_uid(sk);
security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
rcu_read_lock();
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index 15e41c5bea3..bb02e176cb7 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -628,9 +628,9 @@ static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
return;
if (type == NDISC_REDIRECT)
- ip6_redirect(skb, net, 0, 0, sock_net_uid(net, NULL));
+ ip6_redirect(skb, net, 0, 0);
else
- ip6_update_pmtu(skb, net, info, 0, 0, sock_net_uid(net, NULL));
+ ip6_update_pmtu(skb, net, info, 0, 0);
xfrm_state_put(x);
}
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 8abb98c38d3..193274c912f 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -162,7 +162,7 @@ ipv4_connected:
fl6.flowi6_mark = sk->sk_mark;
fl6.fl6_dport = inet->inet_dport;
fl6.fl6_sport = inet->inet_sport;
- fl6.flowi6_uid = sk->sk_uid;
+ fl6.flowi6_uid = sock_i_uid(sk);
if (!fl6.flowi6_oif && (addr_type&IPV6_ADDR_MULTICAST))
fl6.flowi6_oif = np->mcast_oif;
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 4ad65258f54..40ffd72243a 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -447,9 +447,9 @@ static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
return;
if (type == NDISC_REDIRECT)
- ip6_redirect(skb, net, 0, 0, sock_net_uid(net, NULL));
+ ip6_redirect(skb, net, 0, 0);
else
- ip6_update_pmtu(skb, net, info, 0, 0, sock_net_uid(net, NULL));
+ ip6_update_pmtu(skb, net, info, 0, 0);
xfrm_state_put(x);
}
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index b0220040ef2..33101f4e3ee 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -90,9 +90,9 @@ static void icmpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
struct net *net = dev_net(skb->dev);
if (type == ICMPV6_PKT_TOOBIG)
- ip6_update_pmtu(skb, net, info, 0, 0, sock_net_uid(net, NULL));
+ ip6_update_pmtu(skb, net, info, 0, 0);
else if (type == NDISC_REDIRECT)
- ip6_redirect(skb, net, 0, 0, sock_net_uid(net, NULL));
+ ip6_redirect(skb, net, 0, 0);
if (!(type & ICMPV6_INFOMSG_MASK))
if (icmp6->icmp6_type == ICMPV6_ECHO_REQUEST)
@@ -467,7 +467,6 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
fl6.flowi6_oif = iif;
fl6.fl6_icmp_type = type;
fl6.fl6_icmp_code = code;
- fl6.flowi6_uid = sock_net_uid(net, NULL);
security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
sk = icmpv6_xmit_lock(net);
@@ -573,7 +572,6 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
fl6.flowi6_oif = skb->dev->ifindex;
fl6.fl6_icmp_type = ICMPV6_ECHO_REPLY;
fl6.flowi6_mark = mark;
- fl6.flowi6_uid = sock_net_uid(net, NULL);
security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
sk = icmpv6_xmit_lock(net);
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
index a2072a81c93..f92676cb879 100644
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -86,7 +86,7 @@ struct dst_entry *inet6_csk_route_req(struct sock *sk,
fl6->flowi6_mark = inet_rsk(req)->ir_mark;
fl6->fl6_dport = inet_rsk(req)->rmt_port;
fl6->fl6_sport = inet_rsk(req)->loc_port;
- fl6->flowi6_uid = sk->sk_uid;
+ fl6->flowi6_uid = sock_i_uid(sk);
security_req_classify_flow(req, flowi6_to_flowi(fl6));
dst = ip6_dst_lookup_flow(sk, fl6, final_p, false);
@@ -214,7 +214,6 @@ static struct dst_entry *inet6_csk_route_socket(struct sock *sk,
fl6->flowi6_mark = sk->sk_mark;
fl6->fl6_sport = inet->inet_sport;
fl6->fl6_dport = inet->inet_dport;
- fl6->flowi6_uid = sk->sk_uid;
security_sk_classify_flow(sk, flowi6_to_flowi(fl6));
rcu_read_lock();
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 46458ee3193..6de0d44a942 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -167,6 +167,12 @@ static __inline__ void rt6_release(struct rt6_info *rt)
dst_free(&rt->dst);
}
+static void fib6_free_table(struct fib6_table *table)
+{
+ inetpeer_invalidate_tree(&table->tb6_peers);
+ kfree(table);
+}
+
static void fib6_link_table(struct net *net, struct fib6_table *tb)
{
unsigned int h;
@@ -1738,15 +1744,22 @@ out_timer:
static void fib6_net_exit(struct net *net)
{
+ unsigned int i;
+
rt6_ifdown(net, NULL);
del_timer_sync(&net->ipv6.ip6_fib_timer);
-#ifdef CONFIG_IPV6_MULTIPLE_TABLES
- inetpeer_invalidate_tree(&net->ipv6.fib6_local_tbl->tb6_peers);
- kfree(net->ipv6.fib6_local_tbl);
-#endif
- inetpeer_invalidate_tree(&net->ipv6.fib6_main_tbl->tb6_peers);
- kfree(net->ipv6.fib6_main_tbl);
+ for (i = 0; i < FIB6_TABLE_HASHSZ; i++) {
+ struct hlist_head *head = &net->ipv6.fib_table_hash[i];
+ struct hlist_node *tmp;
+ struct fib6_table *tb;
+
+ hlist_for_each_entry_safe(tb, tmp, head, tb6_hlist) {
+ hlist_del(&tb->tb6_hlist);
+ fib6_free_table(tb);
+ }
+ }
+
kfree(net->ipv6.fib_table_hash);
kfree(net->ipv6.rt6_stats);
}
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 31a6b719336..529348e6a98 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -419,7 +419,7 @@ static void ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
if (code == ICMPV6_HDR_FIELD)
teli = ip6_tnl_parse_tlv_enc_lim(skb, skb->data);
- if (teli && teli == info - 2) {
+ if (teli && teli == be32_to_cpu(info) - 2) {
tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->data[teli];
if (tel->encap_limit == 0) {
net_warn_ratelimited("%s: Too small encapsulation limit or routing loop in tunnel!\n",
@@ -431,7 +431,7 @@ static void ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
}
break;
case ICMPV6_PKT_TOOBIG:
- mtu = info - offset;
+ mtu = be32_to_cpu(info) - offset;
if (mtu < IPV6_MIN_MTU)
mtu = IPV6_MIN_MTU;
t->dev->mtu = mtu;
@@ -801,8 +801,6 @@ static inline int ip6gre_xmit_ipv4(struct sk_buff *skb, struct net_device *dev)
if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK)
fl6.flowi6_mark = skb->mark;
- fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL);
-
err = ip6gre_xmit2(skb, dev, dsfield, &fl6, encap_limit, &mtu);
if (err != 0) {
/* XXX: send ICMP error even if DF is not set. */
@@ -853,8 +851,6 @@ static inline int ip6gre_xmit_ipv6(struct sk_buff *skb, struct net_device *dev)
if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK)
fl6.flowi6_mark = skb->mark;
- fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL);
-
err = ip6gre_xmit2(skb, dev, dsfield, &fl6, encap_limit, &mtu);
if (err != 0) {
if (err == -EMSGSIZE)
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 0f514963944..efcba838d4c 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1289,11 +1289,12 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
skb = skb_peek_tail(&sk->sk_write_queue);
cork->length += length;
- if (((length > mtu) ||
- (skb && skb_has_frags(skb))) &&
+ if ((skb && skb_has_frags(skb)) ||
+ (((length + fragheaderlen) > mtu) &&
+ (skb_queue_len(&sk->sk_write_queue) <= 1) &&
(sk->sk_protocol == IPPROTO_UDP) &&
(rt->dst.dev->features & NETIF_F_UFO) &&
- (sk->sk_type == SOCK_DGRAM)) {
+ (sk->sk_type == SOCK_DGRAM))) {
err = ip6_ufo_append_data(sk, getfrag, from, length,
hh_len, fragheaderlen,
transhdrlen, mtu, flags, rt);
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index cd0a8bed1ea..efc77acbe9e 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1096,8 +1096,6 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
memcpy(&fl6, &t->fl.u.ip6, sizeof (fl6));
fl6.flowi6_proto = IPPROTO_IPIP;
- fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL);
-
dsfield = ipv4_get_dsfield(iph);
if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)
@@ -1149,7 +1147,6 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
memcpy(&fl6, &t->fl.u.ip6, sizeof (fl6));
fl6.flowi6_proto = IPPROTO_IPV6;
- fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL);
dsfield = ipv6_get_dsfield(ipv6h);
if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index a4a4e1c2c9f..7af5aee75d9 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -76,9 +76,9 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
return;
if (type == NDISC_REDIRECT)
- ip6_redirect(skb, net, 0, 0, sock_net_uid(net, NULL));
+ ip6_redirect(skb, net, 0, 0);
else
- ip6_update_pmtu(skb, net, info, 0, 0, sock_net_uid(net, NULL));
+ ip6_update_pmtu(skb, net, info, 0, 0);
xfrm_state_put(x);
}
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index e48d26beda4..d38e6a8d8b9 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -27,7 +27,6 @@ int ip6_route_me_harder(struct sk_buff *skb)
struct flowi6 fl6 = {
.flowi6_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0,
.flowi6_mark = skb->mark,
- .flowi6_uid = sock_net_uid(net, skb->sk),
.daddr = iph->daddr,
.saddr = iph->saddr,
};
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c
index 6a38935a9b7..81a687c3c6f 100644
--- a/net/ipv6/ping.c
+++ b/net/ipv6/ping.c
@@ -167,9 +167,9 @@ int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
fl6.daddr = *daddr;
fl6.flowi6_oif = oif;
fl6.flowi6_mark = sk->sk_mark;
- fl6.flowi6_uid = sk->sk_uid;
fl6.fl6_icmp_type = user_icmph.icmp6_type;
fl6.fl6_icmp_code = user_icmph.icmp6_code;
+ fl6.flowi6_uid = sock_i_uid(sk);
security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index d08e231fff3..a7d8bbbb806 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -763,7 +763,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
memset(&fl6, 0, sizeof(fl6));
fl6.flowi6_mark = sk->sk_mark;
- fl6.flowi6_uid = sk->sk_uid;
+ fl6.flowi6_uid = sock_i_uid(sk);
if (sin6) {
if (addr_len < SIN6_LEN_RFC2133)
@@ -1324,7 +1324,7 @@ void raw6_proc_exit(void)
#endif /* CONFIG_PROC_FS */
/* Same as inet6_dgram_ops, sans udp_poll. */
-static const struct proto_ops inet6_sockraw_ops = {
+const struct proto_ops inet6_sockraw_ops = {
.family = PF_INET6,
.owner = THIS_MODULE,
.release = inet6_release,
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 5481f1dd6a5..937e1b40760 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1146,7 +1146,7 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
}
void ip6_update_pmtu(struct sk_buff *skb, struct net *net, __be32 mtu,
- int oif, u32 mark, kuid_t uid)
+ int oif, u32 mark)
{
const struct ipv6hdr *iph = (struct ipv6hdr *) skb->data;
struct dst_entry *dst;
@@ -1159,7 +1159,6 @@ void ip6_update_pmtu(struct sk_buff *skb, struct net *net, __be32 mtu,
fl6.daddr = iph->daddr;
fl6.saddr = iph->saddr;
fl6.flowlabel = ip6_flowinfo(iph);
- fl6.flowi6_uid = uid;
dst = ip6_route_output(net, NULL, &fl6);
if (!dst->error)
@@ -1171,12 +1170,11 @@ EXPORT_SYMBOL_GPL(ip6_update_pmtu);
void ip6_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, __be32 mtu)
{
ip6_update_pmtu(skb, sock_net(sk), mtu,
- sk->sk_bound_dev_if, sk->sk_mark, sk->sk_uid);
+ sk->sk_bound_dev_if, sk->sk_mark);
}
EXPORT_SYMBOL_GPL(ip6_sk_update_pmtu);
-void ip6_redirect(struct sk_buff *skb, struct net *net, int oif, u32 mark,
- kuid_t uid)
+void ip6_redirect(struct sk_buff *skb, struct net *net, int oif, u32 mark)
{
const struct ipv6hdr *iph = (struct ipv6hdr *) skb->data;
struct dst_entry *dst;
@@ -1189,7 +1187,6 @@ void ip6_redirect(struct sk_buff *skb, struct net *net, int oif, u32 mark,
fl6.daddr = iph->daddr;
fl6.saddr = iph->saddr;
fl6.flowlabel = ip6_flowinfo(iph);
- fl6.flowi6_uid = uid;
dst = ip6_route_output(net, NULL, &fl6);
if (!dst->error)
@@ -1200,8 +1197,7 @@ EXPORT_SYMBOL_GPL(ip6_redirect);
void ip6_sk_redirect(struct sk_buff *skb, struct sock *sk)
{
- ip6_redirect(skb, sock_net(sk), sk->sk_bound_dev_if, sk->sk_mark,
- sk->sk_uid);
+ ip6_redirect(skb, sock_net(sk), sk->sk_bound_dev_if, sk->sk_mark);
}
EXPORT_SYMBOL_GPL(ip6_sk_redirect);
@@ -2644,10 +2640,9 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh)
fl6.flowi6_mark = nla_get_u32(tb[RTA_MARK]);
if (tb[RTA_UID])
- fl6.flowi6_uid = make_kuid(current_user_ns(),
- nla_get_u32(tb[RTA_UID]));
+ fl6.flowi6_uid = nla_get_u32(tb[RTA_UID]);
else
- fl6.flowi6_uid = iif ? INVALID_UID : current_uid();
+ fl6.flowi6_uid = (iif ? (uid_t) -1 : current_uid());
if (iif) {
struct net_device *dev;
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index 0428544a2be..701d0656a40 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -243,7 +243,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
fl6.flowi6_mark = ireq->ir_mark;
fl6.fl6_dport = inet_rsk(req)->rmt_port;
fl6.fl6_sport = inet_sk(sk)->inet_sport;
- fl6.flowi6_uid = sk->sk_uid;
+ fl6.flowi6_uid = sock_i_uid(sk);
security_req_classify_flow(req, flowi6_to_flowi(&fl6));
dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false);
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 7775b61bcb3..cb821c3379c 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -253,7 +253,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
fl6.flowi6_mark = sk->sk_mark;
fl6.fl6_dport = usin->sin6_port;
fl6.fl6_sport = inet->inet_sport;
- fl6.flowi6_uid = sk->sk_uid;
+ fl6.flowi6_uid = sock_i_uid(sk);
opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk));
final_p = fl6_update_dst(&fl6, opt, &final);
@@ -802,7 +802,6 @@ static void tcp_v6_send_response(struct sock *sk, struct sk_buff *skb, u32 seq,
fl6.flowi6_mark = IP6_REPLY_MARK(net, skb->mark);
fl6.fl6_dport = t1->dest;
fl6.fl6_sport = t1->source;
- fl6.flowi6_uid = sock_net_uid(net, sk && sk_fullsock(sk) ? sk : NULL);
security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
/* Pass a socket to ip6_dst_lookup either it is for RST
@@ -913,14 +912,8 @@ static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
struct request_sock *req)
{
- /* RFC 7323 2.3
- * The window field (SEG.WND) of every outgoing segment, with the
- * exception of <SYN> segments, MUST be right-shifted by
- * Rcv.Wind.Shift bits:
- */
tcp_v6_send_ack(sk, skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1,
- req->rcv_wnd >> inet_rsk(req)->rcv_wscale,
- tcp_time_stamp, req->ts_recent,
+ req->rcv_wnd, tcp_time_stamp, req->ts_recent,
tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr), 0);
}
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index e873b8dc5cf..82deb263edb 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1148,7 +1148,7 @@ do_udp_sendmsg:
fl6.flowi6_oif = np->sticky_pktinfo.ipi6_ifindex;
fl6.flowi6_mark = sk->sk_mark;
- fl6.flowi6_uid = sk->sk_uid;
+ fl6.flowi6_uid = sock_i_uid(sk);
if (msg->msg_controllen) {
opt = &opt_space;
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 5482090f285..029e1c97fb0 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1139,6 +1139,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
goto out;
}
+ err = -ENOBUFS;
key = ext_hdrs[SADB_EXT_KEY_AUTH - 1];
if (sa->sadb_sa_auth) {
int keysize = 0;
@@ -1150,8 +1151,10 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
if (key)
keysize = (key->sadb_key_bits + 7) / 8;
x->aalg = kmalloc(sizeof(*x->aalg) + keysize, GFP_KERNEL);
- if (!x->aalg)
+ if (!x->aalg) {
+ err = -ENOMEM;
goto out;
+ }
strcpy(x->aalg->alg_name, a->name);
x->aalg->alg_key_len = 0;
if (key) {
@@ -1170,8 +1173,10 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
goto out;
}
x->calg = kmalloc(sizeof(*x->calg), GFP_KERNEL);
- if (!x->calg)
+ if (!x->calg) {
+ err = -ENOMEM;
goto out;
+ }
strcpy(x->calg->alg_name, a->name);
x->props.calgo = sa->sadb_sa_encrypt;
} else {
@@ -1185,8 +1190,10 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
if (key)
keysize = (key->sadb_key_bits + 7) / 8;
x->ealg = kmalloc(sizeof(*x->ealg) + keysize, GFP_KERNEL);
- if (!x->ealg)
+ if (!x->ealg) {
+ err = -ENOMEM;
goto out;
+ }
strcpy(x->ealg->alg_name, a->name);
x->ealg->alg_key_len = 0;
if (key) {
@@ -1234,8 +1241,10 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
struct xfrm_encap_tmpl *natt;
x->encap = kmalloc(sizeof(*x->encap), GFP_KERNEL);
- if (!x->encap)
+ if (!x->encap) {
+ err = -ENOMEM;
goto out;
+ }
natt = x->encap;
n_type = ext_hdrs[SADB_X_EXT_NAT_T_TYPE-1];
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
index 5bd181e296e..8783dfe5ac6 100644
--- a/net/l2tp/l2tp_ip6.c
+++ b/net/l2tp/l2tp_ip6.c
@@ -517,7 +517,6 @@ static int l2tp_ip6_sendmsg(struct kiocb *iocb, struct sock *sk,
memset(&fl6, 0, sizeof(fl6));
fl6.flowi6_mark = sk->sk_mark;
- fl6.flowi6_uid = sk->sk_uid;
if (lsa) {
if (addr_len < SIN6_LEN_RFC2133)
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index 1c6a71c41e6..ca66520b894 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -795,10 +795,8 @@ static int handle_response_icmp(int af, struct sk_buff *skb,
{
unsigned int verdict = NF_DROP;
- if (IP_VS_FWD_METHOD(cp) != 0) {
- pr_err("shouldn't reach here, because the box is on the "
- "half connection in the tun/dr module.\n");
- }
+ if (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ)
+ goto ignore_cp;
/* Ensure the checksum is correct */
if (!skb_csum_unnecessary(skb) && ip_vs_checksum_complete(skb, ihl)) {
@@ -832,6 +830,8 @@ static int handle_response_icmp(int af, struct sk_buff *skb,
ip_vs_notrack(skb);
else
ip_vs_update_conntrack(skb, cp, 0);
+
+ignore_cp:
verdict = NF_ACCEPT;
out:
@@ -1182,8 +1182,11 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int af)
*/
cp = pp->conn_out_get(af, skb, &iph, 0);
- if (likely(cp))
+ if (likely(cp)) {
+ if (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ)
+ goto ignore_cp;
return handle_response(af, skb, pd, cp, &iph, hooknum);
+ }
if (sysctl_nat_icmp_send(net) &&
(pp->protocol == IPPROTO_TCP ||
pp->protocol == IPPROTO_UDP ||
@@ -1225,9 +1228,15 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int af)
}
}
}
+
+out:
IP_VS_DBG_PKT(12, af, pp, skb, 0,
"ip_vs_out: packet continues traversal as normal");
return NF_ACCEPT;
+
+ignore_cp:
+ __ip_vs_conn_put(cp);
+ goto out;
}
/*
diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c
index 1df17614656..c9f131fc4bf 100644
--- a/net/netfilter/nf_conntrack_ecache.c
+++ b/net/netfilter/nf_conntrack_ecache.c
@@ -116,6 +116,7 @@ void nf_conntrack_unregister_notifier(struct net *net,
BUG_ON(notify != new);
RCU_INIT_POINTER(net->ct.nf_conntrack_event_cb, NULL);
mutex_unlock(&nf_ct_ecache_mutex);
+ /* synchronize_rcu() is called from ctnetlink_exit. */
}
EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
@@ -152,6 +153,7 @@ void nf_ct_expect_unregister_notifier(struct net *net,
BUG_ON(notify != new);
RCU_INIT_POINTER(net->ct.nf_expect_event_cb, NULL);
mutex_unlock(&nf_ct_ecache_mutex);
+ /* synchronize_rcu() is called from ctnetlink_exit. */
}
EXPORT_SYMBOL_GPL(nf_ct_expect_unregister_notifier);
diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c
index 1a9545965c0..531ca55f1af 100644
--- a/net/netfilter/nf_conntrack_extend.c
+++ b/net/netfilter/nf_conntrack_extend.c
@@ -53,7 +53,11 @@ nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id,
rcu_read_lock();
t = rcu_dereference(nf_ct_ext_types[id]);
- BUG_ON(t == NULL);
+ if (!t) {
+ rcu_read_unlock();
+ return NULL;
+ }
+
off = ALIGN(sizeof(struct nf_ct_ext), t->align);
len = off + t->len + var_alloc_len;
alloc_size = t->alloc_size + var_alloc_len;
@@ -88,7 +92,10 @@ void *__nf_ct_ext_add_length(struct nf_conn *ct, enum nf_ct_ext_id id,
rcu_read_lock();
t = rcu_dereference(nf_ct_ext_types[id]);
- BUG_ON(t == NULL);
+ if (!t) {
+ rcu_read_unlock();
+ return NULL;
+ }
newoff = ALIGN(old->len, t->align);
newlen = newoff + t->len + var_alloc_len;
@@ -186,6 +193,6 @@ void nf_ct_extend_unregister(struct nf_ct_ext_type *type)
RCU_INIT_POINTER(nf_ct_ext_types[type->id], NULL);
update_alloc_size(type);
mutex_unlock(&nf_ct_ext_type_mutex);
- rcu_barrier(); /* Wait for completion of call_rcu()'s */
+ synchronize_rcu();
}
EXPORT_SYMBOL_GPL(nf_ct_extend_unregister);
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index c5621b5e3f8..6208b7f0572 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -3137,6 +3137,7 @@ static void __exit ctnetlink_exit(void)
#ifdef CONFIG_NETFILTER_NETLINK_QUEUE_CT
RCU_INIT_POINTER(nfq_ct_hook, NULL);
#endif
+ synchronize_rcu();
}
module_init(ctnetlink_init);
diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
index 2bb801e3ee8..7658d018105 100644
--- a/net/netfilter/nf_nat_core.c
+++ b/net/netfilter/nf_nat_core.c
@@ -853,6 +853,8 @@ static void __exit nf_nat_cleanup(void)
#ifdef CONFIG_XFRM
RCU_INIT_POINTER(nf_nat_decode_session_hook, NULL);
#endif
+ synchronize_rcu();
+
for (i = 0; i < NFPROTO_NUMPROTO; i++)
kfree(nf_nat_l4protos[i]);
synchronize_net();
diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c
index 65074dfb938..10d78dc0d2c 100644
--- a/net/netfilter/nfnetlink_cttimeout.c
+++ b/net/netfilter/nfnetlink_cttimeout.c
@@ -431,6 +431,7 @@ static void __exit cttimeout_exit(void)
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
RCU_INIT_POINTER(nf_ct_timeout_find_get_hook, NULL);
RCU_INIT_POINTER(nf_ct_timeout_put_hook, NULL);
+ synchronize_rcu();
#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
}
diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c
index 7011c71646f..c656269c4cf 100644
--- a/net/netfilter/xt_TCPMSS.c
+++ b/net/netfilter/xt_TCPMSS.c
@@ -68,7 +68,7 @@ tcpmss_mangle_packet(struct sk_buff *skb,
tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff);
/* Header cannot be larger than the packet */
- if (tcplen < tcph->doff*4)
+ if (tcplen < tcph->doff*4 || tcph->doff*4 < sizeof(struct tcphdr))
return -1;
if (info->mss == XT_TCPMSS_CLAMP_PMTU) {
@@ -117,6 +117,10 @@ tcpmss_mangle_packet(struct sk_buff *skb,
if (tcplen > tcph->doff*4)
return 0;
+ /* tcph->doff has 4 bits, do not wrap it to 0 */
+ if (tcph->doff >= 15)
+ return 0;
+
/*
* MSS Option not found ?! add it..
*/
diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c
index 2e1c0855159..4c0a6923a3c 100644
--- a/net/netfilter/xt_qtaguid.c
+++ b/net/netfilter/xt_qtaguid.c
@@ -1732,11 +1732,10 @@ static bool qtaguid_mt(const struct sk_buff *skb, struct xt_action_param *par)
res = false;
goto put_sock_ret_res;
}
-
- if (do_tag_stat)
- account_for_uid(skb, sk, sock_uid, par);
-
sock_uid = sk->sk_uid;
+ if (do_tag_stat)
+ account_for_uid(skb, sk, from_kuid(&init_user_ns, sock_uid),
+ par);
/*
* The following two tests fail the match when:
@@ -1763,16 +1762,18 @@ static bool qtaguid_mt(const struct sk_buff *skb, struct xt_action_param *par)
set_sk_callback_lock = true;
read_lock_bh(&sk->sk_callback_lock);
MT_DEBUG("qtaguid[%d]: sk=%p->sk_socket=%p->file=%p\n",
- par->hooknum, sk, sk->sk_socket,
- sk->sk_socket ? sk->sk_socket->file : (void *)-1LL);
+ par->hooknum, sk, sk->sk_socket,
+ sk->sk_socket ? sk->sk_socket->file : (void *)-1LL);
filp = sk->sk_socket ? sk->sk_socket->file : NULL;
if (!filp) {
- res = ((info->match ^ info->invert) & XT_QTAGUID_GID) == 0;
+ res = ((info->match ^ info->invert) &
+ XT_QTAGUID_GID) == 0;
atomic64_inc(&qtu_events.match_no_sk_gid);
goto put_sock_ret_res;
}
MT_DEBUG("qtaguid[%d]: filp...uid=%u\n",
- par->hooknum, filp ? from_kuid(&init_user_ns, filp->f_cred->fsuid) : -1);
+ par->hooknum, filp ?
+ from_kuid(&init_user_ns, filp->f_cred->fsuid) : -1);
if ((gid_gte(filp->f_cred->fsgid, gid_min) &&
gid_lte(filp->f_cred->fsgid, gid_max)) ^
!(info->invert & XT_QTAGUID_GID)) {
@@ -1918,7 +1919,7 @@ static int qtaguid_ctrl_proc_show(struct seq_file *m, void *v)
if (sock_tag_entry != SEQ_START_TOKEN) {
int sk_ref_count;
uid = get_uid_from_tag(sock_tag_entry->tag);
- CT_DEBUG("qtaguid: proc_read(): sk=%pK tag=0x%llx (uid=%u) "
+ CT_DEBUG("qtaguid: proc_read(): sk=%p tag=0x%llx (uid=%u) "
"pid=%u\n",
sock_tag_entry->sk,
sock_tag_entry->tag,
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 0773e3ad991..68934c1bae1 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -3186,14 +3186,19 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
if (optlen != sizeof(val))
return -EINVAL;
- if (po->rx_ring.pg_vec || po->tx_ring.pg_vec)
- return -EBUSY;
if (copy_from_user(&val, optval, sizeof(val)))
return -EFAULT;
if (val > INT_MAX)
return -EINVAL;
- po->tp_reserve = val;
- return 0;
+ lock_sock(sk);
+ if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) {
+ ret = -EBUSY;
+ } else {
+ po->tp_reserve = val;
+ ret = 0;
+ }
+ release_sock(sk);
+ return ret;
}
case PACKET_LOSS:
{
@@ -3341,6 +3346,8 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
case PACKET_HDRLEN:
if (len > sizeof(int))
len = sizeof(int);
+ if (len < sizeof(int))
+ return -EINVAL;
if (copy_from_user(&val, optval, len))
return -EFAULT;
switch (val) {
diff --git a/net/rfkill/core.c b/net/rfkill/core.c
index 959104648f6..352cb5570cb 100644
--- a/net/rfkill/core.c
+++ b/net/rfkill/core.c
@@ -800,8 +800,7 @@ void rfkill_resume_polling(struct rfkill *rfkill)
if (!rfkill->ops->poll)
return;
- queue_delayed_work(system_power_efficient_wq,
- &rfkill->poll_work, 0);
+ schedule_work(&rfkill->poll_work.work);
}
EXPORT_SYMBOL(rfkill_resume_polling);
@@ -909,8 +908,7 @@ static void rfkill_poll(struct work_struct *work)
*/
rfkill->ops->poll(rfkill, rfkill->data);
- queue_delayed_work(system_power_efficient_wq,
- &rfkill->poll_work,
+ schedule_delayed_work(&rfkill->poll_work,
round_jiffies_relative(POLL_INTERVAL));
}
@@ -974,8 +972,7 @@ int __must_check rfkill_register(struct rfkill *rfkill)
INIT_WORK(&rfkill->sync_work, rfkill_sync_work);
if (rfkill->ops->poll)
- queue_delayed_work(system_power_efficient_wq,
- &rfkill->poll_work,
+ schedule_delayed_work(&rfkill->poll_work,
round_jiffies_relative(POLL_INTERVAL));
if (!rfkill->persistent || rfkill_epo_lock_active) {
diff --git a/net/rxrpc/ar-key.c b/net/rxrpc/ar-key.c
index 7633a752c65..10e6e5de36e 100644
--- a/net/rxrpc/ar-key.c
+++ b/net/rxrpc/ar-key.c
@@ -213,7 +213,7 @@ static int rxrpc_krb5_decode_principal(struct krb5_principal *princ,
unsigned int *_toklen)
{
const __be32 *xdr = *_xdr;
- unsigned int toklen = *_toklen, n_parts, loop, tmp;
+ unsigned int toklen = *_toklen, n_parts, loop, tmp, paddedlen;
/* there must be at least one name, and at least #names+1 length
* words */
@@ -243,16 +243,16 @@ static int rxrpc_krb5_decode_principal(struct krb5_principal *princ,
toklen -= 4;
if (tmp <= 0 || tmp > AFSTOKEN_STRING_MAX)
return -EINVAL;
- if (tmp > toklen)
+ paddedlen = (tmp + 3) & ~3;
+ if (paddedlen > toklen)
return -EINVAL;
princ->name_parts[loop] = kmalloc(tmp + 1, GFP_KERNEL);
if (!princ->name_parts[loop])
return -ENOMEM;
memcpy(princ->name_parts[loop], xdr, tmp);
princ->name_parts[loop][tmp] = 0;
- tmp = (tmp + 3) & ~3;
- toklen -= tmp;
- xdr += tmp >> 2;
+ toklen -= paddedlen;
+ xdr += paddedlen >> 2;
}
if (toklen < 4)
@@ -261,16 +261,16 @@ static int rxrpc_krb5_decode_principal(struct krb5_principal *princ,
toklen -= 4;
if (tmp <= 0 || tmp > AFSTOKEN_K5_REALM_MAX)
return -EINVAL;
- if (tmp > toklen)
+ paddedlen = (tmp + 3) & ~3;
+ if (paddedlen > toklen)
return -EINVAL;
princ->realm = kmalloc(tmp + 1, GFP_KERNEL);
if (!princ->realm)
return -ENOMEM;
memcpy(princ->realm, xdr, tmp);
princ->realm[tmp] = 0;
- tmp = (tmp + 3) & ~3;
- toklen -= tmp;
- xdr += tmp >> 2;
+ toklen -= paddedlen;
+ xdr += paddedlen >> 2;
_debug("%s/...@%s", princ->name_parts[0], princ->realm);
@@ -289,7 +289,7 @@ static int rxrpc_krb5_decode_tagged_data(struct krb5_tagged_data *td,
unsigned int *_toklen)
{
const __be32 *xdr = *_xdr;
- unsigned int toklen = *_toklen, len;
+ unsigned int toklen = *_toklen, len, paddedlen;
/* there must be at least one tag and one length word */
if (toklen <= 8)
@@ -303,15 +303,17 @@ static int rxrpc_krb5_decode_tagged_data(struct krb5_tagged_data *td,
toklen -= 8;
if (len > max_data_size)
return -EINVAL;
+ paddedlen = (len + 3) & ~3;
+ if (paddedlen > toklen)
+ return -EINVAL;
td->data_len = len;
if (len > 0) {
td->data = kmemdup(xdr, len, GFP_KERNEL);
if (!td->data)
return -ENOMEM;
- len = (len + 3) & ~3;
- toklen -= len;
- xdr += len >> 2;
+ toklen -= paddedlen;
+ xdr += paddedlen >> 2;
}
_debug("tag %x len %x", td->tag, td->data_len);
@@ -383,7 +385,7 @@ static int rxrpc_krb5_decode_ticket(u8 **_ticket, u16 *_tktlen,
const __be32 **_xdr, unsigned int *_toklen)
{
const __be32 *xdr = *_xdr;
- unsigned int toklen = *_toklen, len;
+ unsigned int toklen = *_toklen, len, paddedlen;
/* there must be at least one length word */
if (toklen <= 4)
@@ -395,6 +397,9 @@ static int rxrpc_krb5_decode_ticket(u8 **_ticket, u16 *_tktlen,
toklen -= 4;
if (len > AFSTOKEN_K5_TIX_MAX)
return -EINVAL;
+ paddedlen = (len + 3) & ~3;
+ if (paddedlen > toklen)
+ return -EINVAL;
*_tktlen = len;
_debug("ticket len %u", len);
@@ -403,9 +408,8 @@ static int rxrpc_krb5_decode_ticket(u8 **_ticket, u16 *_tktlen,
*_ticket = kmemdup(xdr, len, GFP_KERNEL);
if (!*_ticket)
return -ENOMEM;
- len = (len + 3) & ~3;
- toklen -= len;
- xdr += len >> 2;
+ toklen -= paddedlen;
+ xdr += paddedlen >> 2;
}
*_xdr = xdr;
@@ -549,7 +553,7 @@ static int rxrpc_instantiate_xdr(struct key *key, const void *data, size_t datal
{
const __be32 *xdr = data, *token;
const char *cp;
- unsigned int len, tmp, loop, ntoken, toklen, sec_ix;
+ unsigned int len, paddedlen, loop, ntoken, toklen, sec_ix;
int ret;
_enter(",{%x,%x,%x,%x},%zu",
@@ -574,22 +578,21 @@ static int rxrpc_instantiate_xdr(struct key *key, const void *data, size_t datal
if (len < 1 || len > AFSTOKEN_CELL_MAX)
goto not_xdr;
datalen -= 4;
- tmp = (len + 3) & ~3;
- if (tmp > datalen)
+ paddedlen = (len + 3) & ~3;
+ if (paddedlen > datalen)
goto not_xdr;
cp = (const char *) xdr;
for (loop = 0; loop < len; loop++)
if (!isprint(cp[loop]))
goto not_xdr;
- if (len < tmp)
- for (; loop < tmp; loop++)
- if (cp[loop])
- goto not_xdr;
+ for (; loop < paddedlen; loop++)
+ if (cp[loop])
+ goto not_xdr;
_debug("cellname: [%u/%u] '%*.*s'",
- len, tmp, len, len, (const char *) xdr);
- datalen -= tmp;
- xdr += tmp >> 2;
+ len, paddedlen, len, len, (const char *) xdr);
+ datalen -= paddedlen;
+ xdr += paddedlen >> 2;
/* get the token count */
if (datalen < 12)
@@ -610,10 +613,11 @@ static int rxrpc_instantiate_xdr(struct key *key, const void *data, size_t datal
sec_ix = ntohl(*xdr);
datalen -= 4;
_debug("token: [%x/%zx] %x", toklen, datalen, sec_ix);
- if (toklen < 20 || toklen > datalen)
+ paddedlen = (toklen + 3) & ~3;
+ if (toklen < 20 || toklen > datalen || paddedlen > datalen)
goto not_xdr;
- datalen -= (toklen + 3) & ~3;
- xdr += (toklen + 3) >> 2;
+ datalen -= paddedlen;
+ xdr += paddedlen >> 2;
} while (--loop > 0);
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 486c551a4de..ceb8f849777 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -492,7 +492,9 @@ static void sctp_v6_to_addr(union sctp_addr *addr, struct in6_addr *saddr,
{
addr->sa.sa_family = AF_INET6;
addr->v6.sin6_port = port;
+ addr->v6.sin6_flowinfo = 0;
addr->v6.sin6_addr = *saddr;
+ addr->v6.sin6_scope_id = 0;
}
/* Compare addresses exactly.
diff --git a/net/wireless/core.h b/net/wireless/core.h
index f0de1503afe..589135c3775 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -69,7 +69,6 @@ struct cfg80211_registered_device {
struct list_head bss_list;
struct rb_root bss_tree;
u32 bss_generation;
- u32 bss_entries;
struct cfg80211_scan_request *scan_req; /* protected by RTNL */
struct cfg80211_sched_scan_request *sched_scan_req;
unsigned long suspend_at;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index bf0bce47b35..4700f2551b3 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -310,8 +310,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
[NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
[NL80211_ATTR_PID] = { .type = NLA_U32 },
[NL80211_ATTR_4ADDR] = { .type = NLA_U8 },
- [NL80211_ATTR_PMKID] = { .type = NLA_BINARY,
- .len = WLAN_PMKID_LEN },
+ [NL80211_ATTR_PMKID] = { .len = WLAN_PMKID_LEN },
[NL80211_ATTR_DURATION] = { .type = NLA_U32 },
[NL80211_ATTR_COOKIE] = { .type = NLA_U64 },
[NL80211_ATTR_TX_RATES] = { .type = NLA_NESTED },
@@ -366,6 +365,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
[NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 },
[NL80211_ATTR_P2P_CTWINDOW] = { .type = NLA_U8 },
[NL80211_ATTR_P2P_OPPPS] = { .type = NLA_U8 },
+ [NL80211_ATTR_LOCAL_MESH_POWER_MODE] = {. type = NLA_U32 },
[NL80211_ATTR_ACL_POLICY] = {. type = NLA_U32 },
[NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED },
[NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 },
@@ -5212,6 +5212,10 @@ static int validate_scan_freqs(struct nlattr *freqs)
struct nlattr *attr1, *attr2;
int n_channels = 0, tmp1, tmp2;
+ nla_for_each_nested(attr1, freqs, tmp1)
+ if (nla_len(attr1) != sizeof(u32))
+ return 0;
+
nla_for_each_nested(attr1, freqs, tmp1) {
n_channels++;
/*
@@ -8305,6 +8309,9 @@ static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info)
if (err)
return err;
+ if (!tb[NL80211_REKEY_DATA_REPLAY_CTR] || !tb[NL80211_REKEY_DATA_KEK] ||
+ !tb[NL80211_REKEY_DATA_KCK])
+ return -EINVAL;
if (nla_len(tb[NL80211_REKEY_DATA_REPLAY_CTR]) != NL80211_REPLAY_CTR_LEN)
return -ERANGE;
if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN)
@@ -11321,11 +11328,11 @@ int nl80211_init(void)
err = genl_register_mc_group(&nl80211_fam, &nl80211_testmode_mcgrp);
if (err)
goto err_out;
-#endif
err = genl_register_mc_group(&nl80211_fam, &nl80211_vendor_mcgrp);
if (err)
goto err_out;
+#endif
err = netlink_register_notifier(&nl80211_netlink_notifier);
if (err)
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 30ed665f1c6..1ef1f150a10 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1588,8 +1588,8 @@ static void reg_process_hint(struct regulatory_request *reg_request,
break;
default:
if (reg_initiator == NL80211_REGDOM_SET_BY_USER)
- queue_delayed_work(system_power_efficient_wq,
- &reg_timeout, msecs_to_jiffies(3142));
+ schedule_delayed_work(&reg_timeout,
+ msecs_to_jiffies(3142));
break;
}
}
@@ -2191,8 +2191,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
if (!request_wiphy &&
(lr->initiator == NL80211_REGDOM_SET_BY_DRIVER ||
lr->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)) {
- queue_delayed_work(system_power_efficient_wq,
- &reg_timeout, 0);
+ schedule_delayed_work(&reg_timeout, 0);
return -ENODEV;
}
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 950d1a0b39a..b63fa8d8d37 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -55,20 +55,7 @@
* also linked into the probe response struct.
*/
-/*
- * Limit the number of BSS entries stored in mac80211. Each one is
- * a bit over 4k at most, so this limits to roughly 4-5M of memory.
- * If somebody wants to really attack this though, they'd likely
- * use small beacons, and only one type of frame, limiting each of
- * the entries to a much smaller size (in order to generate more
- * entries in total, so overhead is bigger.)
- */
-static int bss_entries_limit = 1000;
-module_param(bss_entries_limit, int, 0644);
-MODULE_PARM_DESC(bss_entries_limit,
- "limit to number of scan BSS entries (per wiphy, default 1000)");
-
-#define IEEE80211_SCAN_RESULT_EXPIRE (3 * HZ)
+#define IEEE80211_SCAN_RESULT_EXPIRE (7 * HZ)
static void bss_free(struct cfg80211_internal_bss *bss)
{
@@ -148,10 +135,6 @@ static bool __cfg80211_unlink_bss(struct cfg80211_registered_device *dev,
list_del_init(&bss->list);
rb_erase(&bss->rbn, &dev->bss_tree);
- dev->bss_entries--;
- WARN_ONCE((dev->bss_entries == 0) ^ list_empty(&dev->bss_list),
- "rdev bss entries[%d]/list[empty:%d] corruption\n",
- dev->bss_entries, list_empty(&dev->bss_list));
bss_ref_put(dev, bss);
return true;
}
@@ -355,40 +338,6 @@ void cfg80211_bss_expire(struct cfg80211_registered_device *dev)
__cfg80211_bss_expire(dev, jiffies - IEEE80211_SCAN_RESULT_EXPIRE);
}
-static bool cfg80211_bss_expire_oldest(struct cfg80211_registered_device *rdev)
-{
- struct cfg80211_internal_bss *bss, *oldest = NULL;
- bool ret;
-
- lockdep_assert_held(&rdev->bss_lock);
-
- list_for_each_entry(bss, &rdev->bss_list, list) {
- if (atomic_read(&bss->hold))
- continue;
-
- if (!list_empty(&bss->hidden_list) &&
- !bss->pub.hidden_beacon_bss)
- continue;
-
- if (oldest && time_before(oldest->ts, bss->ts))
- continue;
- oldest = bss;
- }
-
- if (WARN_ON(!oldest))
- return false;
-
- /*
- * The callers make sure to increase rdev->bss_generation if anything
- * gets removed (and a new entry added), so there's no need to also do
- * it here.
- */
-
- ret = __cfg80211_unlink_bss(rdev, oldest);
- WARN_ON(!ret);
- return ret;
-}
-
const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len)
{
while (len > 2 && ies[0] != eid) {
@@ -673,7 +622,6 @@ static bool cfg80211_combine_bsses(struct cfg80211_registered_device *dev,
const u8 *ie;
int i, ssidlen;
u8 fold = 0;
- u32 n_entries = 0;
ies = rcu_access_pointer(new->pub.beacon_ies);
if (WARN_ON(!ies))
@@ -697,12 +645,6 @@ static bool cfg80211_combine_bsses(struct cfg80211_registered_device *dev,
/* This is the bad part ... */
list_for_each_entry(bss, &dev->bss_list, list) {
- /*
- * we're iterating all the entries anyway, so take the
- * opportunity to validate the list length accounting
- */
- n_entries++;
-
if (!ether_addr_equal(bss->pub.bssid, new->pub.bssid))
continue;
if (bss->pub.channel != new->pub.channel)
@@ -732,10 +674,6 @@ static bool cfg80211_combine_bsses(struct cfg80211_registered_device *dev,
new->pub.beacon_ies);
}
- WARN_ONCE(n_entries != dev->bss_entries,
- "rdev bss entries[%d]/list[len:%d] corruption\n",
- dev->bss_entries, n_entries);
-
return true;
}
@@ -880,14 +818,7 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
}
}
- if (dev->bss_entries >= bss_entries_limit &&
- !cfg80211_bss_expire_oldest(dev)) {
- kfree(new);
- goto drop;
- }
-
list_add_tail(&new->list, &dev->bss_list);
- dev->bss_entries++;
rb_insert_bss(dev, new);
found = new;
}
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index ea970b8002a..10c556e373b 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -3201,9 +3201,15 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
struct xfrm_state *x_new[XFRM_MAX_DEPTH];
struct xfrm_migrate *mp;
+ /* Stage 0 - sanity checks */
if ((err = xfrm_migrate_check(m, num_migrate)) < 0)
goto out;
+ if (dir >= XFRM_POLICY_MAX) {
+ err = -EINVAL;
+ goto out;
+ }
+
/* Stage 1 - find policy */
if ((pol = xfrm_migrate_policy_find(sel, dir, type)) == NULL) {
err = -ENOENT;
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 862e54de538..dc50af30312 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -404,6 +404,9 @@ static inline int xfrm_replay_verify_len(struct xfrm_replay_state_esn *replay_es
if (up->replay_window > up->bmp_len * sizeof(__u32) * 8)
return -EINVAL;
+ if (up->replay_window > up->bmp_len * sizeof(__u32) * 8)
+ return -EINVAL;
+
return 0;
}
diff --git a/scripts/setlocalversion b/scripts/setlocalversion
index 09ad65a0c16..8fcc5ce0572 100755
--- a/scripts/setlocalversion
+++ b/scripts/setlocalversion
@@ -184,7 +184,7 @@ else
# LOCALVERSION= is not specified
if test "${LOCALVERSION+set}" != "set"; then
scm=$(scm_version --short)
- res="$res"
+ res="$res${scm:++}"
fi
fi
diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c
index c4c8df4b214..b7d7cffe734 100644
--- a/security/keys/encrypted-keys/encrypted.c
+++ b/security/keys/encrypted-keys/encrypted.c
@@ -315,6 +315,13 @@ static struct key *request_user_key(const char *master_desc, u8 **master_key,
down_read(&ukey->sem);
upayload = ukey->payload.data;
+ if (!upayload) {
+ /* key was revoked before we acquired its semaphore */
+ up_read(&ukey->sem);
+ key_put(ukey);
+ ukey = ERR_PTR(-EKEYREVOKED);
+ goto error;
+ }
*master_key = upayload->data;
*master_keylen = upayload->datalen;
error:
@@ -428,7 +435,7 @@ static int init_blkcipher_desc(struct blkcipher_desc *desc, const u8 *key,
static struct key *request_master_key(struct encrypted_key_payload *epayload,
u8 **master_key, size_t *master_keylen)
{
- struct key *mkey = NULL;
+ struct key *mkey = ERR_PTR(-EINVAL);
if (!strncmp(epayload->master_desc, KEY_TRUSTED_PREFIX,
KEY_TRUSTED_PREFIX_LEN)) {
diff --git a/security/keys/internal.h b/security/keys/internal.h
index d4f1468b9b5..ce6d4634a84 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -126,7 +126,7 @@ extern key_ref_t search_process_keyrings(struct key_type *type,
key_match_func_t match,
const struct cred *cred);
-extern struct key *find_keyring_by_name(const char *name, bool skip_perm_check);
+extern struct key *find_keyring_by_name(const char *name, bool uid_keyring);
extern int install_user_keyrings(void);
extern int install_thread_keyring_to_cred(struct cred *);
diff --git a/security/keys/key.c b/security/keys/key.c
index 6595b2dd89f..248c2e73137 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -299,6 +299,8 @@ struct key *key_alloc(struct key_type *type, const char *desc,
if (!(flags & KEY_ALLOC_NOT_IN_QUOTA))
key->flags |= 1 << KEY_FLAG_IN_QUOTA;
+ if (flags & KEY_ALLOC_UID_KEYRING)
+ key->flags |= 1 << KEY_FLAG_UID_KEYRING;
memset(&key->type_data, 0, sizeof(key->type_data));
@@ -897,6 +899,16 @@ error:
*/
__key_link_end(keyring, ktype, prealloc);
+ key = key_ref_to_ptr(key_ref);
+ if (test_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags)) {
+ ret = wait_for_key_construction(key, true);
+ if (ret < 0) {
+ key_ref_put(key_ref);
+ key_ref = ERR_PTR(ret);
+ goto error_free_prep;
+ }
+ }
+
key_ref = __key_update(key_ref, &prep);
goto error_free_prep;
}
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 066baa1926b..7576f49eeb3 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -93,7 +93,7 @@ SYSCALL_DEFINE5(add_key, const char __user *, _type,
payload = NULL;
vm = false;
- if (_payload) {
+ if (plen) {
ret = -ENOMEM;
payload = kmalloc(plen, GFP_KERNEL | __GFP_NOWARN);
if (!payload) {
@@ -327,7 +327,7 @@ long keyctl_update_key(key_serial_t id,
/* pull the payload in if one was supplied */
payload = NULL;
- if (_payload) {
+ if (plen) {
ret = -ENOMEM;
payload = kmalloc(plen, GFP_KERNEL);
if (!payload)
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 6ece7f2e570..b0cabf68c67 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -583,15 +583,15 @@ found:
/*
* Find a keyring with the specified name.
*
- * All named keyrings in the current user namespace are searched, provided they
- * grant Search permission directly to the caller (unless this check is
- * skipped). Keyrings whose usage points have reached zero or who have been
- * revoked are skipped.
+ * Only keyrings that have nonzero refcount, are not revoked, and are owned by a
+ * user in the current user namespace are considered. If @uid_keyring is %true,
+ * the keyring additionally must have been allocated as a user or user session
+ * keyring; otherwise, it must grant Search permission directly to the caller.
*
* Returns a pointer to the keyring with the keyring's refcount having being
* incremented on success. -ENOKEY is returned if a key could not be found.
*/
-struct key *find_keyring_by_name(const char *name, bool skip_perm_check)
+struct key *find_keyring_by_name(const char *name, bool uid_keyring)
{
struct key *keyring;
int bucket;
@@ -619,10 +619,15 @@ struct key *find_keyring_by_name(const char *name, bool skip_perm_check)
if (strcmp(keyring->description, name) != 0)
continue;
- if (!skip_perm_check &&
- key_permission(make_key_ref(keyring, 0),
- KEY_SEARCH) < 0)
- continue;
+ if (uid_keyring) {
+ if (!test_bit(KEY_FLAG_UID_KEYRING,
+ &keyring->flags))
+ continue;
+ } else {
+ if (key_permission(make_key_ref(keyring, 0),
+ KEY_SEARCH) < 0)
+ continue;
+ }
/* we've got a match but we might end up racing with
* key_cleanup() if the keyring is currently 'dead'
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 7a5abb2b9d5..1c963ff8968 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -76,7 +76,9 @@ int install_user_keyrings(void)
if (IS_ERR(uid_keyring)) {
uid_keyring = keyring_alloc(buf, user->uid, INVALID_GID,
cred, user_keyring_perm,
- KEY_ALLOC_IN_QUOTA, NULL);
+ KEY_ALLOC_UID_KEYRING |
+ KEY_ALLOC_IN_QUOTA,
+ NULL);
if (IS_ERR(uid_keyring)) {
ret = PTR_ERR(uid_keyring);
goto error;
@@ -92,7 +94,9 @@ int install_user_keyrings(void)
session_keyring =
keyring_alloc(buf, user->uid, INVALID_GID,
cred, user_keyring_perm,
- KEY_ALLOC_IN_QUOTA, NULL);
+ KEY_ALLOC_UID_KEYRING |
+ KEY_ALLOC_IN_QUOTA,
+ NULL);
if (IS_ERR(session_keyring)) {
ret = PTR_ERR(session_keyring);
goto error_release;
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index ec8c4883bd3..386aafb2e69 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -626,7 +626,7 @@ static int avc_latest_notif_update(int seqno, int is_insert)
spin_lock_irqsave(&notif_lock, flag);
if (is_insert) {
if (seqno < avc_cache.latest_notif) {
- pr_debug(KERN_WARNING "SELinux: avc: seqno %d < latest_notif %d\n",
+ printk(KERN_WARNING "SELinux: avc: seqno %d < latest_notif %d\n",
seqno, avc_cache.latest_notif);
ret = -EAGAIN;
}
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 3dc771cbd3b..60e1a58c544 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -435,6 +435,7 @@ static int sb_finish_set_opts(struct super_block *sb)
if (!strcmp(sb->s_type->name, "sysfs") ||
!strcmp(sb->s_type->name, "pstore") ||
!strcmp(sb->s_type->name, "debugfs") ||
+ !strcmp(sb->s_type->name, "tracefs") ||
!strcmp(sb->s_type->name, "rootfs"))
sbsec->flags |= SE_SBLABELSUPP;
@@ -445,6 +446,13 @@ static int sb_finish_set_opts(struct super_block *sb)
if (strncmp(sb->s_type->name, "rootfs", sizeof("rootfs")) == 0)
sbsec->flags |= SE_SBLABELSUPP;
+ /*
+ * Special handling for rootfs. Is genfs but supports
+ * setting SELinux context on in-core inodes.
+ */
+ if (strncmp(sb->s_type->name, "rootfs", sizeof("rootfs")) == 0)
+ sbsec->flags |= SE_SBLABELSUPP;
+
/* Initialize the root inode. */
rc = inode_doinit_with_dentry(root_inode, root);
@@ -710,6 +718,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
sbsec->flags |= SE_SBPROC | SE_SBGENFS;
if (!strcmp(sb->s_type->name, "debugfs") ||
+ !strcmp(sb->s_type->name, "tracefs") ||
!strcmp(sb->s_type->name, "sysfs") ||
!strcmp(sb->s_type->name, "pstore"))
sbsec->flags |= SE_SBGENFS;
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
index 11a2f16c0f9..bbe684ddc81 100644
--- a/sound/core/compress_offload.c
+++ b/sound/core/compress_offload.c
@@ -46,13 +46,6 @@
#define U32_MAX ((u32)~0U)
-/* struct snd_compr_codec_caps overflows the ioctl bit size for some
- * architectures, so we need to disable the relevant ioctls.
- */
-#if _IOC_SIZEBITS < 14
-#define COMPR_CODEC_CAPS_OVERFLOW
-#endif
-
/* TODO:
* - add substream support for multiple devices in case of
* SND_DYNAMIC_MINORS is not used
@@ -452,7 +445,6 @@ out:
return retval;
}
-#ifndef COMPR_CODEC_CAPS_OVERFLOW
static int
snd_compr_get_codec_caps(struct snd_compr_stream *stream, unsigned long arg)
{
@@ -476,7 +468,6 @@ out:
kfree(caps);
return retval;
}
-#endif /* !COMPR_CODEC_CAPS_OVERFLOW */
/* revisit this with snd_pcm_preallocate_xxx */
static int snd_compr_allocate_buffer(struct snd_compr_stream *stream,
@@ -851,13 +842,6 @@ static long snd_compr_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
mutex_lock(&stream->device->lock);
switch (_IOC_NR(cmd)) {
-
-#ifndef COMPR_CODEC_CAPS_OVERFLOW
- case _IOC_NR(SNDRV_COMPRESS_GET_CODEC_CAPS):
- retval = snd_compr_get_codec_caps(stream, arg);
- break;
-#endif
-
case _IOC_NR(SNDRV_COMPRESS_SET_PARAMS):
retval = snd_compr_set_params(stream, arg);
break;
diff --git a/sound/core/control.c b/sound/core/control.c
index 251bc575f5c..c3928261136 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -1088,7 +1088,7 @@ static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kcontrol,
mutex_lock(&ue->card->user_ctl_lock);
change = ue->tlv_data_size != size;
if (!change)
- change = memcmp(ue->tlv_data, new_data, size);
+ change = memcmp(ue->tlv_data, new_data, size) != 0;
kfree(ue->tlv_data);
ue->tlv_data = new_data;
ue->tlv_data_size = size;
diff --git a/sound/soc/msm/qdsp6v2/Makefile b/sound/soc/msm/qdsp6v2/Makefile
index 2dfca79ef50..96137eac2f5 100644
--- a/sound/soc/msm/qdsp6v2/Makefile
+++ b/sound/soc/msm/qdsp6v2/Makefile
@@ -9,7 +9,6 @@ snd-soc-qdsp6v2-objs += msm-dai-q6-v2.o msm-pcm-q6-v2.o msm-pcm-routing-v2.o \
obj-$(CONFIG_SND_SOC_QDSP6V2) += snd-soc-qdsp6v2.o msm-pcm-dtmf-v2.o \
msm-dai-stub-v2.o
obj-$(CONFIG_SND_HWDEP) += msm-pcm-routing-devdep.o
-obj-$(CONFIG_DTS_EAGLE) += msm-dts-eagle.o
obj-$(CONFIG_DOLBY_DAP) += msm-dolby-dap-config.o
obj-$(CONFIG_DOLBY_DS2) += msm-ds2-dap-config.o
obj-$(CONFIG_DTS_SRS_TM) += msm-dts-srs-tm-config.o
diff --git a/sound/soc/msm/qdsp6v2/audio_cal_utils.c b/sound/soc/msm/qdsp6v2/audio_cal_utils.c
index 562e9a121d4..07c5b5b7f0f 100644
--- a/sound/soc/msm/qdsp6v2/audio_cal_utils.c
+++ b/sound/soc/msm/qdsp6v2/audio_cal_utils.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -136,8 +136,6 @@ size_t get_cal_info_size(int32_t cal_type)
case ULP_LSM_CAL_TYPE:
size = sizeof(struct audio_cal_info_lsm);
break;
- case DTS_EAGLE_CAL_TYPE:
- size = 0;
case AUDIO_CORE_METAINFO_CAL_TYPE:
size = sizeof(struct audio_cal_info_metainfo);
break;
@@ -263,8 +261,6 @@ size_t get_user_cal_type_size(int32_t cal_type)
case ULP_LSM_CAL_TYPE:
size = sizeof(struct audio_cal_type_lsm);
break;
- case DTS_EAGLE_CAL_TYPE:
- size = 0;
case AUDIO_CORE_METAINFO_CAL_TYPE:
size = sizeof(struct audio_cal_type_metainfo);
break;
@@ -567,7 +563,6 @@ static struct cal_block_data *create_cal_block(struct cal_type_data *cal_type,
memset(cal_block, 0, sizeof(*cal_block));
INIT_LIST_HEAD(&cal_block->list);
- list_add_tail(&cal_block->list, &cal_type->cal_blocks);
cal_block->map_data.ion_map_handle = basic_cal->cal_data.mem_handle;
if (basic_cal->cal_data.mem_handle > 0) {
@@ -599,6 +594,7 @@ static struct cal_block_data *create_cal_block(struct cal_type_data *cal_type,
goto err;
}
cal_block->buffer_number = basic_cal->cal_hdr.buffer_number;
+ list_add_tail(&cal_block->list, &cal_type->cal_blocks);
pr_debug("%s: created block for cal type %d, buf num %d, map handle %d, map size %zd paddr 0x%pK!\n",
__func__, cal_type->info.reg.cal_type,
cal_block->buffer_number,
@@ -608,6 +604,10 @@ static struct cal_block_data *create_cal_block(struct cal_type_data *cal_type,
done:
return cal_block;
err:
+ kfree(cal_block->cal_info);
+ cal_block->cal_info = NULL;
+ kfree(cal_block->client_info);
+ cal_block->client_info = NULL;
kfree(cal_block);
cal_block = NULL;
return cal_block;
diff --git a/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c
index 1c08842c784..1286d318578 100644
--- a/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -15,7 +15,6 @@
#include <sound/q6asm-v2.h>
#include <sound/compress_params.h>
#include <sound/msm-audio-effects-q6-v2.h>
-#include <sound/msm-dts-eagle.h>
#include <sound/devdep_params.h>
#define MAX_ENABLE_CMD_SIZE 32
@@ -49,26 +48,6 @@ bool msm_audio_effects_is_effmodule_supp_in_top(int effect_module,
case EQ_MODULE:
switch (topology) {
case ASM_STREAM_POSTPROC_TOPO_ID_SA_PLUS:
- case ASM_STREAM_POSTPROC_TOPO_ID_HPX_PLUS:
- case ASM_STREAM_POSTPROC_TOPO_ID_HPX_MASTER:
- return true;
- default:
- return false;
- }
- case DTS_EAGLE_MODULE:
- switch (topology) {
- case ASM_STREAM_POSTPROC_TOPO_ID_DTS_HPX:
- case ASM_STREAM_POSTPROC_TOPO_ID_HPX_PLUS:
- case ASM_STREAM_POSTPROC_TOPO_ID_HPX_MASTER:
- return true;
- default:
- return false;
- }
- case SOFT_VOLUME2_MODULE:
- case DTS_EAGLE_MODULE_ENABLE:
- switch (topology) {
- case ASM_STREAM_POSTPROC_TOPO_ID_HPX_PLUS:
- case ASM_STREAM_POSTPROC_TOPO_ID_HPX_MASTER:
return true;
default:
return false;
@@ -176,7 +155,7 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"VIRT ENABLE", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_VIRTUALIZER;
*updt_params++ =
@@ -204,7 +183,7 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"VIRT STRENGTH", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_VIRTUALIZER;
*updt_params++ =
@@ -232,7 +211,7 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"VIRT OUT_TYPE", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_VIRTUALIZER;
*updt_params++ =
@@ -260,7 +239,7 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"VIRT GAIN_ADJUST", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_VIRTUALIZER;
*updt_params++ =
@@ -276,7 +255,7 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac,
break;
}
}
- if (params_length && !msm_dts_eagle_is_hpx_on() && (rc == 0))
+ if (params_length && (rc == 0))
q6asm_send_audio_effects_params(ac, params,
params_length);
else
@@ -339,7 +318,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_ENABLE", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -367,7 +346,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_MODE", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -395,7 +374,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_PRESET", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -423,7 +402,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_WET_MIX", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -451,7 +430,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_GAIN_ADJUST", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -479,7 +458,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_ROOM_LEVEL", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -507,7 +486,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_ROOM_HF_LEVEL", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -535,7 +514,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_DECAY_TIME", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -563,7 +542,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_DECAY_HF_RATIO", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -591,7 +570,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_REFLECTIONS_LEVEL", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -619,7 +598,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_REFLECTIONS_DELAY", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -647,7 +626,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_LEVEL", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -675,7 +654,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_DELAY", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -703,7 +682,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_DIFFUSION", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -731,7 +710,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_DENSITY", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -747,7 +726,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
break;
}
}
- if (params_length && !msm_dts_eagle_is_hpx_on() && (rc == 0))
+ if (params_length && (rc == 0))
q6asm_send_audio_effects_params(ac, params,
params_length);
else
@@ -811,7 +790,7 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"BASS_BOOST_ENABLE", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_BASS_BOOST;
*updt_params++ =
@@ -839,7 +818,7 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"BASS_BOOST_MODE", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_BASS_BOOST;
*updt_params++ =
@@ -867,7 +846,7 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"BASS_BOOST_STRENGTH", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_BASS_BOOST;
*updt_params++ =
@@ -883,7 +862,7 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac,
break;
}
}
- if (params_length && !msm_dts_eagle_is_hpx_on() && (rc == 0))
+ if (params_length && (rc == 0))
q6asm_send_audio_effects_params(ac, params,
params_length);
else
@@ -945,7 +924,7 @@ int msm_audio_effects_pbe_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"PBE_ENABLE", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_PBE;
*updt_params++ =
@@ -971,7 +950,7 @@ int msm_audio_effects_pbe_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"PBE_PARAM", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_PBE;
*updt_params++ =
@@ -1056,7 +1035,7 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"EQ_ENABLE", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_POPLESS_EQUALIZER;
*updt_params++ =
@@ -1124,7 +1103,7 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"EQ_CONFIG", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_POPLESS_EQUALIZER;
*updt_params++ =
@@ -1175,7 +1154,7 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"EQ_BAND_INDEX", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_POPLESS_EQUALIZER;
*updt_params++ =
@@ -1207,7 +1186,7 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"EQ_SINGLE_BAND_FREQ", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_POPLESS_EQUALIZER;
*updt_params++ =
@@ -1223,7 +1202,7 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac,
break;
}
}
- if (params_length && !msm_dts_eagle_is_hpx_on() && (rc == 0))
+ if (params_length && (rc == 0))
q6asm_send_audio_effects_params(ac, params,
params_length);
else
@@ -1297,7 +1276,7 @@ static int __msm_audio_effects_volume_handler(struct audio_client *ac,
"VOLUME/VOLUME2_GAIN_2CH",
rc);
if (rc != 0)
- break;
+ goto invalid_config;
if (instance == SOFT_VOLUME_INSTANCE_2)
*updt_params++ =
ASM_MODULE_ID_VOL_CTRL2;
@@ -1346,7 +1325,7 @@ static int __msm_audio_effects_volume_handler(struct audio_client *ac,
"VOLUME/VOLUME2_GAIN_MASTER",
rc);
if (rc != 0)
- break;
+ goto invalid_config;
if (instance == SOFT_VOLUME_INSTANCE_2)
*updt_params++ =
ASM_MODULE_ID_VOL_CTRL2;
diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
index da110c53102..bc0278c1769 100644
--- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
@@ -43,8 +43,6 @@
#include <sound/compress_offload.h>
#include <sound/compress_driver.h>
#include <sound/msm-audio-effects-q6-v2.h>
-#include <sound/msm-dts-eagle.h>
-
#include "msm-pcm-routing-v2.h"
#include "audio_ocmem.h"
@@ -83,15 +81,6 @@ const DECLARE_TLV_DB_LINEAR(msm_compr_vol_gain, 0,
#define MAX_NUMBER_OF_STREAMS 2
-/*
- * Max size for getting DTS EAGLE Param through kcontrol
- * Safe for both 32 and 64 bit platforms
- * 64 = size of kcontrol value array on 64 bit platform
- * 4 = size of parameters Eagle expects before cast to 64 bits
- * 40 = size of dts_eagle_param_desc + module_id cast to 64 bits
- */
-#define DTS_EAGLE_MAX_PARAM_SIZE_FOR_ALSA ((64 * 4) - 40)
-
struct msm_compr_gapless_state {
bool set_next_stream_id;
int32_t stream_opened[MAX_NUMBER_OF_STREAMS];
@@ -310,11 +299,6 @@ static int msm_compr_set_volume(struct snd_compr_stream *cstream,
if (rc < 0)
pr_err("%s: Send vol gain command failed rc=%d\n",
__func__, rc);
- else
- if (msm_dts_eagle_set_stream_gain(prtd->audio_client,
- volume_l, volume_r))
- pr_debug("%s: DTS_EAGLE send stream gain failed\n",
- __func__);
return rc;
}
@@ -929,26 +913,6 @@ static int msm_compr_init_pp_params(struct snd_compr_stream *cstream,
};
switch (ac->topology) {
- case ASM_STREAM_POSTPROC_TOPO_ID_HPX_PLUS: /* HPX + SA+ topology */
-
- ret = q6asm_set_softvolume_v2(ac, &softvol,
- SOFT_VOLUME_INSTANCE_1);
- if (ret < 0)
- pr_err("%s: Send SoftVolume Param failed ret=%d\n",
- __func__, ret);
-
- ret = q6asm_set_softvolume_v2(ac, &softvol,
- SOFT_VOLUME_INSTANCE_2);
- if (ret < 0)
- pr_err("%s: Send SoftVolume2 Param failed ret=%d\n",
- __func__, ret);
- /*
- * HPX module init is trigerred from HAL using ioctl
- * DTS_EAGLE_MODULE_ENABLE when stream starts
- */
- break;
- case ASM_STREAM_POSTPROC_TOPO_ID_DTS_HPX: /* HPX topology */
- break;
default:
ret = q6asm_set_softvolume_v2(ac, &softvol,
SOFT_VOLUME_INSTANCE_1);
@@ -2451,23 +2415,6 @@ static int msm_compr_audio_effects_config_put(struct snd_kcontrol *kcontrol,
&(audio_effects->equalizer),
values);
break;
- case DTS_EAGLE_MODULE:
- pr_debug("%s: DTS_EAGLE_MODULE\n", __func__);
- if (!msm_audio_effects_is_effmodule_supp_in_top(effects_module,
- prtd->audio_client->topology))
- return 0;
- msm_dts_eagle_handle_asm(NULL, (void *)values, true,
- false, prtd->audio_client, NULL);
- break;
- case DTS_EAGLE_MODULE_ENABLE:
- pr_debug("%s: DTS_EAGLE_MODULE_ENABLE\n", __func__);
- if (msm_audio_effects_is_effmodule_supp_in_top(effects_module,
- prtd->audio_client->topology))
- msm_dts_eagle_enable_asm(prtd->audio_client,
- (bool)values[0],
- AUDPROC_MODULE_ID_DTS_HPX_PREMIX);
-
- break;
case SOFT_VOLUME_MODULE:
pr_debug("%s: SOFT_VOLUME_MODULE\n", __func__);
break;
@@ -2496,7 +2443,6 @@ static int msm_compr_audio_effects_config_get(struct snd_kcontrol *kcontrol,
struct msm_compr_audio_effects *audio_effects = NULL;
struct snd_compr_stream *cstream = NULL;
struct msm_compr_audio *prtd = NULL;
- long *values = &(ucontrol->value.integer.value[0]);
pr_debug("%s\n", __func__);
if (fe_id >= MSM_FRONTEND_DAI_MAX) {
@@ -2516,28 +2462,6 @@ static int msm_compr_audio_effects_config_get(struct snd_kcontrol *kcontrol,
return -EINVAL;
}
- switch (audio_effects->query.mod_id) {
- case DTS_EAGLE_MODULE:
- pr_debug("%s: DTS_EAGLE_MODULE handling queued get\n",
- __func__);
- values[0] = (long)audio_effects->query.mod_id;
- values[1] = (long)audio_effects->query.parm_id;
- values[2] = (long)audio_effects->query.size;
- values[3] = (long)audio_effects->query.offset;
- values[4] = (long)audio_effects->query.device;
- if (values[2] > DTS_EAGLE_MAX_PARAM_SIZE_FOR_ALSA) {
- pr_err("%s: DTS_EAGLE_MODULE parameter's requested size (%li) too large (max size is %i)\n",
- __func__, values[2],
- DTS_EAGLE_MAX_PARAM_SIZE_FOR_ALSA);
- return -EINVAL;
- }
- msm_dts_eagle_handle_asm(NULL, (void *)&values[1],
- true, true, prtd->audio_client, NULL);
- break;
- default:
- pr_err("%s: Invalid effects config module\n", __func__);
- return -EINVAL;
- }
return 0;
}
diff --git a/sound/soc/msm/qdsp6v2/msm-dts-eagle.c b/sound/soc/msm/qdsp6v2/msm-dts-eagle.c
deleted file mode 100644
index 3e76acf9ea0..00000000000
--- a/sound/soc/msm/qdsp6v2/msm-dts-eagle.c
+++ /dev/null
@@ -1,1655 +0,0 @@
-/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 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.
- */
-
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-#include <linux/msm_ion.h>
-#include <linux/mm.h>
-#include <linux/msm_audio_ion.h>
-#include <linux/vmalloc.h>
-#include <sound/core.h>
-#include <sound/soc.h>
-#include <sound/pcm.h>
-#include <sound/q6adm-v2.h>
-#include <sound/q6asm-v2.h>
-#include <sound/apr_audio-v2.h>
-#include <sound/q6audio-v2.h>
-#include <sound/audio_effects.h>
-#include <sound/hwdep.h>
-#include <sound/msm-dts-eagle.h>
-#include <sound/q6core.h>
-
-#include "msm-pcm-routing-v2.h"
-
-#define ION_MEM_SIZE 131072
-#define DEPC_MAX_SIZE 524288
-
-#define MPST AUDPROC_MODULE_ID_DTS_HPX_POSTMIX
-#define MPRE AUDPROC_MODULE_ID_DTS_HPX_PREMIX
-
-#define eagle_vol_dbg(fmt, ...) \
- pr_debug("DTS_EAGLE_DRIVER_VOLUME: " fmt "\n", ##__VA_ARGS__)
-#define eagle_vol_err(fmt, ...) \
- pr_err("DTS_EAGLE_DRIVER_VOLUME: " fmt "\n", ##__VA_ARGS__)
-#define eagle_drv_dbg(fmt, ...) \
- pr_debug("DTS_EAGLE_DRIVER: " fmt "\n", ##__VA_ARGS__)
-#define eagle_drv_err(fmt, ...) \
- pr_err("DTS_EAGLE_DRIVER: " fmt "\n", ##__VA_ARGS__)
-#define eagle_precache_dbg(fmt, ...) \
- pr_debug("DTS_EAGLE_DRIVER_SENDCACHE_PRE: " fmt "\n", ##__VA_ARGS__)
-#define eagle_precache_err(fmt, ...) \
- pr_err("DTS_EAGLE_DRIVER_SENDCACHE_PRE: " fmt "\n", ##__VA_ARGS__)
-#define eagle_postcache_dbg(fmt, ...) \
- pr_debug("DTS_EAGLE_DRIVER_SENDCACHE_POST: " fmt "\n", ##__VA_ARGS__)
-#define eagle_postcache_err(fmt, ...) \
- pr_err("DTS_EAGLE_DRIVER_SENDCACHE_POST: " fmt "\n", ##__VA_ARGS__)
-#define eagle_ioctl_dbg(fmt, ...) \
- pr_debug("DTS_EAGLE_DRIVER_IOCTL: " fmt "\n", ##__VA_ARGS__)
-#define eagle_ioctl_err(fmt, ...) \
- pr_err("DTS_EAGLE_DRIVER_IOCTL: " fmt "\n", ##__VA_ARGS__)
-#define eagle_asm_dbg(fmt, ...) \
- pr_debug("DTS_EAGLE_DRIVER_ASM: " fmt "\n", ##__VA_ARGS__)
-#define eagle_asm_err(fmt, ...) \
- pr_err("DTS_EAGLE_DRIVER_ASM: " fmt "\n", ##__VA_ARGS__)
-#define eagle_adm_dbg(fmt, ...) \
- pr_debug("DTS_EAGLE_DRIVER_ADM: " fmt "\n", ##__VA_ARGS__)
-#define eagle_adm_err(fmt, ...) \
- pr_err("DTS_EAGLE_DRIVER_ADM: " fmt "\n", ##__VA_ARGS__)
-#define eagle_enable_dbg(fmt, ...) \
- pr_debug("DTS_EAGLE_ENABLE: " fmt "\n", ##__VA_ARGS__)
-#define eagle_enable_err(fmt, ...) \
- pr_err("DTS_EAGLE_ENABLE: " fmt "\n", ##__VA_ARGS__)
-#define eagle_ioctl_info(fmt, ...) \
- pr_err("DTS_EAGLE_IOCTL: " fmt "\n", ##__VA_ARGS__)
-
-enum {
- AUDIO_DEVICE_OUT_EARPIECE = 0,
- AUDIO_DEVICE_OUT_SPEAKER,
- AUDIO_DEVICE_OUT_WIRED_HEADSET,
- AUDIO_DEVICE_OUT_WIRED_HEADPHONE,
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO,
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET,
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT,
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES,
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER,
- AUDIO_DEVICE_OUT_AUX_DIGITAL,
- AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET,
- AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET,
- AUDIO_DEVICE_OUT_USB_ACCESSORY,
- AUDIO_DEVICE_OUT_USB_DEVICE,
- AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
- AUDIO_DEVICE_OUT_ANC_HEADSET,
- AUDIO_DEVICE_OUT_ANC_HEADPHONE,
- AUDIO_DEVICE_OUT_PROXY,
- AUDIO_DEVICE_OUT_FM,
- AUDIO_DEVICE_OUT_FM_TX,
-
- AUDIO_DEVICE_OUT_COUNT
-};
-
-#define AUDIO_DEVICE_COMBO 0x400000 /* bit 23 */
-
-enum { /* cache block */
- CB_0 = 0,
- CB_1,
- CB_2,
- CB_3,
- CB_4,
- CB_5,
- CB_6,
- CB_7,
-
- CB_COUNT
-};
-
-enum { /* cache block description */
- CBD_DEV_MASK = 0,
- CBD_OFFSG,
- CBD_CMD0,
- CBD_SZ0,
- CBD_OFFS1,
- CBD_CMD1,
- CBD_SZ1,
- CBD_OFFS2,
- CBD_CMD2,
- CBD_SZ2,
- CBD_OFFS3,
- CBD_CMD3,
- CBD_SZ3,
-
- CBD_COUNT,
-};
-
-static s32 _fx_logN(s32 x)
-{
- s32 t, y = 0xa65af;
- if (x < 0x00008000) {
- x <<= 16; y -= 0xb1721; }
- if (x < 0x00800000) {
- x <<= 8; y -= 0x58b91; }
- if (x < 0x08000000) {
- x <<= 4; y -= 0x2c5c8; }
- if (x < 0x20000000) {
- x <<= 2; y -= 0x162e4; }
- if (x < 0x40000000) {
- x <<= 1; y -= 0x0b172; }
- t = x + (x >> 1);
- if ((t & 0x80000000) == 0) {
- x = t; y -= 0x067cd; }
- t = x + (x >> 2);
- if ((t & 0x80000000) == 0) {
- x = t; y -= 0x03920; }
- t = x + (x >> 3);
- if ((t & 0x80000000) == 0) {
- x = t; y -= 0x01e27; }
- t = x + (x >> 4);
- if ((t & 0x80000000) == 0) {
- x = t; y -= 0x00f85; }
- t = x + (x >> 5);
- if ((t & 0x80000000) == 0) {
- x = t; y -= 0x007e1; }
- t = x + (x >> 6);
- if ((t & 0x80000000) == 0) {
- x = t; y -= 0x003f8; }
- t = x + (x >> 7);
- if ((t & 0x80000000) == 0) {
- x = t; y -= 0x001fe; }
- x = 0x80000000 - x;
- y -= x >> 15;
- return y;
-}
-
-static inline void *_getd(struct dts_eagle_param_desc *depd)
-{
- return (void *)(((char *)depd) + sizeof(struct dts_eagle_param_desc));
-}
-
-static int _ref_cnt;
-/* dts eagle parameter cache */
-static char *_depc;
-static u32 _depc_size;
-static s32 _c_bl[CB_COUNT][CBD_COUNT];
-static u32 _device_primary;
-static u32 _device_all;
-/* ION states */
-static struct ion_client *_ion_client;
-static struct ion_handle *_ion_handle;
-static struct param_outband _po;
-static struct audio_client *_ac_NT;
-static struct ion_client *_ion_client_NT;
-static struct ion_handle *_ion_handle_NT;
-static struct param_outband _po_NT;
-
-#define SEC_BLOB_MAX_CNT 10
-#define SEC_BLOB_MAX_SIZE 0x4004 /*extra 4 for size*/
-static char *_sec_blob[SEC_BLOB_MAX_CNT];
-
-/* multi-copp support */
-static int _cidx[AFE_MAX_PORTS] = {-1};
-
-/* volume controls */
-#define VOL_CMD_CNT_MAX 10
-static u32 _vol_cmd_cnt;
-static s32 **_vol_cmds;
-struct vol_cmds_d {
- s32 d[4];
-};
-static struct vol_cmds_d *_vol_cmds_d;
-static const s32 _log10_10_inv_x20 = 0x0008af84;
-
-/* hpx master control */
-static u32 _is_hpx_enabled;
-/* flag to identify if slim be to be used */
-static u32 _use_slim_be;
-
-static void _volume_cmds_free(void)
-{
- int i;
- for (i = 0; i < _vol_cmd_cnt; i++)
- kfree(_vol_cmds[i]);
- _vol_cmd_cnt = 0;
- kfree(_vol_cmds);
- kfree(_vol_cmds_d);
- _vol_cmds = NULL;
- _vol_cmds_d = NULL;
-}
-
-static s32 _volume_cmds_alloc1(s32 size)
-{
- _volume_cmds_free();
- _vol_cmd_cnt = size;
- _vol_cmds = kzalloc(_vol_cmd_cnt * sizeof(int *), GFP_KERNEL);
- if (_vol_cmds) {
- _vol_cmds_d = kzalloc(_vol_cmd_cnt * sizeof(struct vol_cmds_d),
- GFP_KERNEL);
- } else
- _vol_cmd_cnt = 0;
- if (_vol_cmds_d)
- return 0;
- _volume_cmds_free();
- return -ENOMEM;
-}
-
-/* assumes size is equal or less than 0xFFF */
-static s32 _volume_cmds_alloc2(s32 idx, s32 size)
-{
- kfree(_vol_cmds[idx]);
- _vol_cmds[idx] = kzalloc(size, GFP_KERNEL);
- if (_vol_cmds[idx])
- return 0;
- _vol_cmds_d[idx].d[0] = 0;
- return -ENOMEM;
-}
-
-static void _init_cb_descs(void)
-{
- int i;
- for (i = 0; i < CB_COUNT; i++) {
- _c_bl[i][CBD_DEV_MASK] = 0;
- _c_bl[i][CBD_OFFSG] = _c_bl[i][CBD_OFFS1] =
- _c_bl[i][CBD_OFFS2] = _c_bl[i][CBD_OFFS3] =
- 0xFFFFFFFF;
- _c_bl[i][CBD_CMD0] = _c_bl[i][CBD_SZ0] =
- _c_bl[i][CBD_CMD1] = _c_bl[i][CBD_SZ1] =
- _c_bl[i][CBD_CMD2] = _c_bl[i][CBD_SZ2] =
- _c_bl[i][CBD_CMD3] = _c_bl[i][CBD_SZ3] = 0;
- }
-}
-
-static u32 _get_dev_mask_for_pid(int pid)
-{
- switch (pid) {
- case SLIMBUS_0_RX:
- case AFE_PORT_ID_PRIMARY_MI2S_RX:
- return (1 << AUDIO_DEVICE_OUT_EARPIECE) |
- (1 << AUDIO_DEVICE_OUT_SPEAKER) |
- (1 << AUDIO_DEVICE_OUT_WIRED_HEADSET) |
- (1 << AUDIO_DEVICE_OUT_WIRED_HEADPHONE) |
- (1 << AUDIO_DEVICE_OUT_ANC_HEADSET) |
- (1 << AUDIO_DEVICE_OUT_ANC_HEADPHONE);
- case INT_BT_SCO_RX:
- return (1 << AUDIO_DEVICE_OUT_BLUETOOTH_SCO) |
- (1 << AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) |
- (1 << AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT);
- case RT_PROXY_PORT_001_RX:
- return (1 << AUDIO_DEVICE_OUT_BLUETOOTH_A2DP) |
- (1 << AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES) |
- (1 << AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER) |
- (1 << AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET) |
- (1 << AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) |
- (1 << AUDIO_DEVICE_OUT_USB_ACCESSORY) |
- (1 << AUDIO_DEVICE_OUT_USB_DEVICE) |
- (1 << AUDIO_DEVICE_OUT_PROXY);
- case HDMI_RX:
- return 1 << AUDIO_DEVICE_OUT_AUX_DIGITAL;
- case INT_FM_RX:
- return 1 << AUDIO_DEVICE_OUT_FM;
- case INT_FM_TX:
- return 1 << AUDIO_DEVICE_OUT_FM_TX;
- default:
- return 0;
- }
-}
-
-static int _get_pid_from_dev(u32 device)
-{
- if (device & (1 << AUDIO_DEVICE_OUT_EARPIECE) ||
- device & (1 << AUDIO_DEVICE_OUT_SPEAKER) ||
- device & (1 << AUDIO_DEVICE_OUT_WIRED_HEADSET) ||
- device & (1 << AUDIO_DEVICE_OUT_WIRED_HEADPHONE) ||
- device & (1 << AUDIO_DEVICE_OUT_ANC_HEADSET) ||
- device & (1 << AUDIO_DEVICE_OUT_ANC_HEADPHONE)) {
- if (_use_slim_be) {
- return SLIMBUS_0_RX;
- } else {
- return AFE_PORT_ID_PRIMARY_MI2S_RX;
- }
- } else if (device & (1 << AUDIO_DEVICE_OUT_BLUETOOTH_SCO) ||
- device & (1 << AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) ||
- device & (1 << AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT)) {
- return INT_BT_SCO_RX;
- } else if (device & (1 << AUDIO_DEVICE_OUT_BLUETOOTH_A2DP) ||
- device & (1 << AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES) ||
- device & (1 << AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER) ||
- device & (1 << AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET) ||
- device & (1 << AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) ||
- device & (1 << AUDIO_DEVICE_OUT_USB_ACCESSORY) ||
- device & (1 << AUDIO_DEVICE_OUT_USB_DEVICE) ||
- device & (1 << AUDIO_DEVICE_OUT_PROXY)) {
- return RT_PROXY_PORT_001_RX;
- } else if (device & (1 << AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
- return HDMI_RX;
- } else if (device & (1 << AUDIO_DEVICE_OUT_FM)) {
- return INT_FM_RX;
- } else if (device & (1 << AUDIO_DEVICE_OUT_FM_TX)) {
- return INT_FM_TX;
- }
- return 0;
-}
-
-static s32 _get_cb_for_dev(int device)
-{
- s32 i;
- if (device & AUDIO_DEVICE_COMBO) {
- for (i = 0; i < CB_COUNT; i++) {
- if ((_c_bl[i][CBD_DEV_MASK] & device) == device)
- return i;
- }
- } else {
- for (i = 0; i < CB_COUNT; i++) {
- if ((_c_bl[i][CBD_DEV_MASK] & device) &&
- !(_c_bl[i][CBD_DEV_MASK] & AUDIO_DEVICE_COMBO))
- return i;
- }
- }
- eagle_drv_err("%s: device %i not found", __func__, device);
- return -EINVAL;
-}
-
-static int _is_port_open_and_eagle(int pid)
-{
- if (msm_routing_check_backend_enabled(pid))
- return 1;
- return 1;
-}
-
-static int _isNTDevice(u32 device)
-{
- if (device &
- ((1 << AUDIO_DEVICE_OUT_BLUETOOTH_SCO) |
- (1 << AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) |
- (1 << AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT) |
- (1 << AUDIO_DEVICE_OUT_BLUETOOTH_A2DP) |
- (1 << AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES) |
- (1 << AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER) |
- (1 << AUDIO_DEVICE_OUT_AUX_DIGITAL)))
- return 1;
- return 0;
-}
-
-static void _reg_ion_mem(void)
-{
- int rc;
- rc = msm_audio_ion_alloc("DTS_EAGLE", &_ion_client, &_ion_handle,
- ION_MEM_SIZE, &_po.paddr, &_po.size, &_po.kvaddr);
- if (rc)
- eagle_drv_err("%s: msm audio ion alloc failed with %i",
- __func__, rc);
-}
-
-static void _unreg_ion_mem(void)
-{
- int rc;
- rc = msm_audio_ion_free(_ion_client, _ion_handle);
- if (rc)
- eagle_drv_err("%s: msm audio ion alloc failed with %i",
- __func__, rc);
-}
-
-static void _reg_ion_mem_NT(void)
-{
- int rc;
- eagle_drv_dbg("%s: NT ion mem", __func__);
- rc = msm_audio_ion_alloc("DTS_EAGLE", &_ion_client_NT,
- &_ion_handle_NT, ION_MEM_SIZE,
- &_po_NT.paddr, &_po_NT.size, &_po_NT.kvaddr);
- if (rc) {
- eagle_drv_err("%s: msm audio ion alloc failed", __func__);
- return;
- }
- rc = q6asm_memory_map(_ac_NT, _po_NT.paddr,
- IN, _po_NT.size, 1);
- if (rc < 0) {
- eagle_drv_err("%s: memory map failed", __func__);
- msm_audio_ion_free(_ion_client_NT, _ion_handle_NT);
- _ion_client_NT = NULL;
- _ion_handle_NT = NULL;
- }
-}
-
-static void _unreg_ion_mem_NT(void)
-{
- int rc;
- rc = q6asm_memory_unmap(_ac_NT, _po_NT.paddr, IN);
- if (rc < 0)
- eagle_drv_err("%s: mem unmap failed", __func__);
- rc = msm_audio_ion_free(_ion_client_NT, _ion_handle_NT);
- if (rc < 0)
- eagle_drv_err("%s: mem free failed", __func__);
-
- _ion_client_NT = NULL;
- _ion_handle_NT = NULL;
-}
-
-static struct audio_client *_getNTDeviceAC(void)
-{
- return _ac_NT;
-}
-
-static void _set_audioclient(struct audio_client *ac)
-{
- _ac_NT = ac;
- _reg_ion_mem_NT();
-}
-
-static void _clear_audioclient(void)
-{
- _unreg_ion_mem_NT();
- _ac_NT = NULL;
-}
-
-
-static int _sendcache_pre(struct audio_client *ac)
-{
- uint32_t offset, size;
- int32_t cidx, cmd, err = 0;
- cidx = _get_cb_for_dev(_device_primary);
- if (cidx < 0) {
- eagle_precache_err("%s: no cache for primary device %i found",
- __func__, _device_primary);
- return -EINVAL;
- }
- offset = _c_bl[cidx][CBD_OFFSG];
- cmd = _c_bl[cidx][CBD_CMD0];
- size = _c_bl[cidx][CBD_SZ0];
- /* check for integer overflow */
- if (offset > (UINT_MAX - size))
- err = -EINVAL;
- if ((_depc_size == 0) || !_depc || (size == 0) ||
- cmd == 0 || ((offset + size) > _depc_size) || (err != 0)) {
- eagle_precache_err("%s: primary device %i cache index %i general error - cache size = %u, cache ptr = %pK, offset = %u, size = %u, cmd = %i",
- __func__, _device_primary, cidx, _depc_size, _depc,
- offset, size, cmd);
- return -EINVAL;
- }
-
- if ((offset < (UINT_MAX - 124)) && ((offset + 124) < _depc_size))
- eagle_precache_dbg("%s: first 6 integers %i %i %i %i %i %i (30th %i)",
- __func__, *((int *)&_depc[offset]),
- *((int *)&_depc[offset+4]),
- *((int *)&_depc[offset+8]),
- *((int *)&_depc[offset+12]),
- *((int *)&_depc[offset+16]),
- *((int *)&_depc[offset+20]),
- *((int *)&_depc[offset+120]));
- eagle_precache_dbg("%s: sending full data block to port, with cache index = %d device mask 0x%X, param = 0x%X, offset = %u, and size = %u",
- __func__, cidx, _c_bl[cidx][CBD_DEV_MASK], cmd, offset, size);
-
- if (q6asm_dts_eagle_set(ac, cmd, size, (void *)&_depc[offset],
- NULL, MPRE))
- eagle_precache_err("%s: q6asm_dts_eagle_set failed with id = %d and size = %u",
- __func__, cmd, size);
- else
- eagle_precache_dbg("%s: q6asm_dts_eagle_set succeeded with id = %d and size = %u",
- __func__, cmd, size);
- return 0;
-}
-
-static int _sendcache_post(int port_id, int copp_idx, int topology)
-{
- int cidx = -1, cmd, mask, index, err = 0;
- uint32_t offset, size;
-
- if (port_id == -1) {
- cidx = _get_cb_for_dev(_device_primary);
- if (cidx < 0) {
- eagle_postcache_err("%s: no cache for primary device %i found. Port id was 0x%X",
- __func__, _device_primary, port_id);
- return -EINVAL;
- }
- goto NT_MODE_GOTO;
- }
-
- index = adm_validate_and_get_port_index(port_id);
- if (index < 0) {
- eagle_postcache_err("%s: Invalid port idx %d port_id %#x",
- __func__, index, port_id);
- return -EINVAL;
- }
- eagle_postcache_dbg("%s: valid port idx %d for port_id %#x set to %i",
- __func__, index, port_id, copp_idx);
- _cidx[index] = copp_idx;
-
- mask = _get_dev_mask_for_pid(port_id);
- if (mask & _device_primary) {
- cidx = _get_cb_for_dev(_device_primary);
- if (cidx < 0) {
- eagle_postcache_err("%s: no cache for primary device %i found. Port id was 0x%X",
- __func__, _device_primary, port_id);
- return -EINVAL;
- }
- } else if (mask & _device_all) {
- cidx = _get_cb_for_dev(_device_all);
- if (cidx < 0) {
- eagle_postcache_err("%s: no cache for combo device %i found. Port id was 0x%X",
- __func__, _device_all, port_id);
- return -EINVAL;
- }
- } else {
- eagle_postcache_err("%s: port id 0x%X not for primary or combo device %i",
- __func__, port_id, _device_primary);
- return -EINVAL;
- }
-
-NT_MODE_GOTO:
- offset = _c_bl[cidx][CBD_OFFSG] + _c_bl[cidx][CBD_OFFS2];
- cmd = _c_bl[cidx][CBD_CMD2];
- size = _c_bl[cidx][CBD_SZ2];
-
- /* check for integer overflow */
- if (offset > (UINT_MAX - size))
- err = -EINVAL;
- if ((_depc_size == 0) || !_depc || (err != 0) || (size == 0) ||
- (cmd == 0) || (offset + size) > _depc_size) {
- eagle_postcache_err("%s: primary device %i cache index %i port_id 0x%X general error - cache size = %u, cache ptr = %pK, offset = %u, size = %u, cmd = %i",
- __func__, _device_primary, cidx, port_id,
- _depc_size, _depc, offset, size, cmd);
- return -EINVAL;
- }
-
- if ((offset < (UINT_MAX - 24)) && ((offset + 24) < _depc_size))
- eagle_postcache_dbg("%s: first 6 integers %i %i %i %i %i %i",
- __func__, *((int *)&_depc[offset]),
- *((int *)&_depc[offset+4]),
- *((int *)&_depc[offset+8]),
- *((int *)&_depc[offset+12]),
- *((int *)&_depc[offset+16]),
- *((int *)&_depc[offset+20]));
- eagle_postcache_dbg("%s: sending full data block to port, with cache index = %d device mask 0x%X, port_id = 0x%X, param = 0x%X, offset = %u, and size = %u",
- __func__, cidx, _c_bl[cidx][CBD_DEV_MASK], port_id, cmd,
- offset, size);
-
- if (_ac_NT) {
- eagle_postcache_dbg("%s: NT Route detected", __func__);
- if (q6asm_dts_eagle_set(_getNTDeviceAC(), cmd, size,
- (void *)&_depc[offset],
- &_po_NT, MPST))
- eagle_postcache_err("%s: q6asm_dts_eagle_set failed with id = 0x%X and size = %u",
- __func__, cmd, size);
- } else if (adm_dts_eagle_set(port_id, copp_idx, cmd,
- (void *)&_depc[offset], size) < 0)
- eagle_postcache_err("%s: adm_dts_eagle_set failed with id = 0x%X and size = %u",
- __func__, cmd, size);
- else
- eagle_postcache_dbg("%s: adm_dts_eagle_set succeeded with id = 0x%X and size = %u",
- __func__, cmd, size);
- return 0;
-}
-
-static int _enable_post_get_control(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = _is_hpx_enabled;
- return 0;
-}
-
-static int _enable_post_put_control(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int idx = 0, be_index = 0, port_id, topology;
- int flag = ucontrol->value.integer.value[0];
- struct msm_pcm_routing_bdai_data msm_bedai;
- eagle_drv_dbg("%s: flag %d", __func__, flag);
-
- _is_hpx_enabled = flag ? true : false;
- msm_pcm_routing_acquire_lock();
- /* send cache postmix params when hpx is set On */
- for (be_index = 0; be_index < MSM_BACKEND_DAI_MAX; be_index++) {
- msm_pcm_routing_get_bedai_info(be_index, &msm_bedai);
- port_id = msm_bedai.port_id;
- if (!(((port_id == SLIMBUS_0_RX) ||
- (port_id == RT_PROXY_PORT_001_RX) ||
- (port_id == AFE_PORT_ID_PRIMARY_MI2S_RX)) &&
- msm_bedai.active))
- continue;
- for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) {
- topology = adm_get_topology_for_port_copp_idx(
- port_id, idx);
- if (topology ==
- ADM_CMD_COPP_OPEN_TOPOLOGY_ID_DTS_HPX) {
- msm_dts_eagle_enable_adm(port_id, idx,
- _is_hpx_enabled);
- }
- }
- }
- msm_pcm_routing_release_lock();
- return 0;
-}
-
-static const struct snd_kcontrol_new _hpx_enabled_controls[] = {
- SOC_SINGLE_EXT("Set HPX OnOff", SND_SOC_NOPM, 0, 1, 0,
- _enable_post_get_control, _enable_post_put_control)
-};
-
-static int _be_post_get_control(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = _use_slim_be;
- return 0;
-}
-
-static int _be_post_put_control(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- _use_slim_be = ucontrol->value.integer.value[0];
- eagle_drv_dbg(" valuse of _use_slim_be == %d", _use_slim_be);
- return 0;
-}
-
-static const struct snd_kcontrol_new _hpx_be_controls[] = {
- SOC_SINGLE_EXT("Set HPX ActiveBe", SND_SOC_NOPM, 0, 1, 0,
- _be_post_get_control, _be_post_put_control)
-};
-/**
- * msm_dts_ion_memmap() - helper function to map ION memory
- * @po_: Out of band memory structure used as memory.
- *
- * Assign already allocated ION memory for mapping it to dsp.
- *
- * Return: No return value.
- */
-void msm_dts_ion_memmap(struct param_outband *po_)
-{
- po_->size = ION_MEM_SIZE;
- po_->kvaddr = _po.kvaddr;
- po_->paddr = _po.paddr;
-}
-
-/**
- * msm_dts_eagle_enable_asm() - Enable/disable dts module
- * @ac: Enable/disable module in ASM session associated with this audio client.
- * @enable: Enable/disable the dts module.
- * @module: module id.
- *
- * Enable/disable specified dts module id in asm.
- *
- * Return: Return failure if any.
- */
-int msm_dts_eagle_enable_asm(struct audio_client *ac, u32 enable, int module)
-{
- int ret = 0;
- eagle_enable_dbg("%s: enable = %i on module %i",
- __func__, enable, module);
- _is_hpx_enabled = enable;
- ret = q6asm_dts_eagle_set(ac, AUDPROC_PARAM_ID_ENABLE,
- sizeof(enable), &enable,
- NULL, module);
- if (_is_hpx_enabled) {
- if (module == MPRE)
- _sendcache_pre(ac);
- else if (module == MPST)
- _sendcache_post(-1, 0, 0);
- }
- return ret;
-}
-
-/**
- * msm_dts_eagle_enable_adm() - Enable/disable dts module in adm
- * @port_id: Send enable/disable param to this port id.
- * @copp_idx: Send enable/disable param to the relevant copp.
- * @enable: Enable/disable the dts module.
- *
- * Enable/disable dts module in adm.
- *
- * Return: Return failure if any.
- */
-int msm_dts_eagle_enable_adm(int port_id, int copp_idx, u32 enable)
-{
- int ret = 0;
- eagle_enable_dbg("%s: enable = %i", __func__, enable);
- _is_hpx_enabled = enable;
- ret = adm_dts_eagle_set(port_id, copp_idx, AUDPROC_PARAM_ID_ENABLE,
- (char *)&enable, sizeof(enable));
- if (_is_hpx_enabled)
- _sendcache_post(port_id, copp_idx, MPST);
- return ret;
-}
-
-/**
- * msm_dts_eagle_add_controls() - Add mixer control to Enable/Disable DTS HPX
- * @platform: Add mixer controls to this platform.
- *
- * Add mixer control to Enable/Disable DTS HPX module in ADM.
- *
- * Return: No return value.
- */
-void msm_dts_eagle_add_controls(struct snd_soc_platform *platform)
-{
- snd_soc_add_platform_controls(platform, _hpx_enabled_controls,
- ARRAY_SIZE(_hpx_enabled_controls));
- snd_soc_add_platform_controls(platform, _hpx_be_controls,
- ARRAY_SIZE(_hpx_be_controls));
-
-}
-
-/**
- * msm_dts_eagle_set_stream_gain() - Set stream gain to DTS Premix module
- * @ac: Set stream gain to ASM session associated with this audio client.
- * @lgain: Left gain value.
- * @rgain: Right gain value.
- *
- * Set stream gain to DTS Premix module in ASM.
- *
- * Return: failure or success.
- */
-int msm_dts_eagle_set_stream_gain(struct audio_client *ac, int lgain, int rgain)
-{
- u32 i, val;
- s32 idx, err = 0;
-
- eagle_vol_dbg("%s: - entry: vol_cmd_cnt = %u, lgain = %i, rgain = %i",
- __func__, _vol_cmd_cnt, lgain, rgain);
-
- if (_depc_size == 0) {
- eagle_vol_dbg("%s: driver cache not initialized", __func__);
- return -EINVAL;
- }
-
- for (i = 0; i < _vol_cmd_cnt; i++) {
- if (_vol_cmds_d[i].d[0] & 0x8000) {
- idx = (sizeof(struct dts_eagle_param_desc)/sizeof(int))
- + (_vol_cmds_d[i].d[0] & 0x3FF);
- val = _fx_logN(((s32)(lgain+rgain)) << 2);
- val = ((long long)val * _log10_10_inv_x20) >> 16;
- _vol_cmds[i][idx] = (s32)clamp((int)(((long long)val *
- _vol_cmds_d[i].d[1]) >> 16),
- _vol_cmds_d[i].d[2],
- _vol_cmds_d[i].d[3]);
- eagle_vol_dbg("%s: loop %u cmd desc found %i, idx = %i. volume info: lgain = %i, rgain = %i, volume = %i (scale %i, min %i, max %i)",
- __func__, i, _vol_cmds_d[i].d[0], idx, lgain,
- rgain, _vol_cmds[i][idx], _vol_cmds_d[i].d[1],
- _vol_cmds_d[i].d[2], _vol_cmds_d[i].d[3]);
- }
- idx = _get_cb_for_dev(_device_primary);
- if (idx < 0) {
- eagle_vol_err("%s: no cache for primary device %i found",
- __func__, _device_primary);
- return -EINVAL;
- }
- val = _c_bl[idx][CBD_OFFSG] + _vol_cmds[i][2];
- /* check for integer overflow */
- if (val > (UINT_MAX - _vol_cmds[i][1]))
- err = -EINVAL;
- if ((err != 0) || ((val + _vol_cmds[i][1]) > _depc_size)) {
- eagle_vol_err("%s: volume size (%u) + offset (%i) out of bounds %i",
- __func__, val, _vol_cmds[i][1], _depc_size);
- return -EINVAL;
- }
- memcpy((void *)&_depc[val], &_vol_cmds[i][4], _vol_cmds[i][1]);
- if (q6asm_dts_eagle_set(ac, _vol_cmds[i][0],
- _vol_cmds[i][1], (void *)&_depc[val], NULL, MPRE))
- eagle_vol_err("%s: loop %u - volume set failed with id 0x%X, size %i, offset %i, cmd_desc %i, scale %i, min %i, max %i, data(...) %i",
- __func__, i, _vol_cmds[i][0], _vol_cmds[i][1],
- _vol_cmds[i][2], _vol_cmds_d[i].d[0],
- _vol_cmds_d[i].d[1], _vol_cmds_d[i].d[2],
- _vol_cmds_d[i].d[3], _vol_cmds[i][4]);
- else
- eagle_vol_dbg("%s: loop %u - volume set succeeded with id 0x%X, size %i, offset %i, cmd_desc %i, scale %i, min %i, max %i, data(...) %i",
- __func__, i, _vol_cmds[i][0], _vol_cmds[i][1],
- _vol_cmds[i][2], _vol_cmds_d[i].d[0],
- _vol_cmds_d[i].d[1], _vol_cmds_d[i].d[2],
- _vol_cmds_d[i].d[3], _vol_cmds[i][4]);
- }
- return 0;
-}
-
-/**
- * msm_dts_eagle_handle_asm() - Set or Get params from ASM
- * @depd: DTS Eagle Params structure.
- * @buf: Buffer to get queried param value.
- * @for_pre: For premix module or postmix module.
- * @get: Getting param from DSP or setting param.
- * @ac: Set/Get from ASM session associated with this audio client.
- * @po: Out of band memory to set or get postmix params.
- *
- * Set or Get params from modules in ASM session.
- *
- * Return: Return failure if any.
- */
-int msm_dts_eagle_handle_asm(struct dts_eagle_param_desc *depd, char *buf,
- bool for_pre, bool get, struct audio_client *ac,
- struct param_outband *po)
-{
- struct dts_eagle_param_desc depd_ = {0};
- s32 ret = 0, isALSA = 0, err = 0, i, mod = for_pre ? MPRE : MPST;
- u32 offset;
-
- eagle_asm_dbg("%s: set/get asm", __func__);
-
- /* special handling for ALSA route, to accommodate 64 bit platforms */
- if (depd == NULL) {
- long *arg_ = (long *)buf;
- depd = &depd_;
- depd->id = (u32)*arg_++;
- depd->size = (u32)*arg_++;
- depd->offset = (s32)*arg_++;
- depd->device = (u32)*arg_++;
- buf = (char *)arg_;
- isALSA = 1;
- }
-
- if (depd->size & 1) {
- eagle_asm_err("%s: parameter size %u is not a multiple of 2",
- __func__, depd->size);
- return -EINVAL;
- }
-
- if (get) {
- void *buf_, *buf_m = NULL;
- eagle_asm_dbg("%s: get requested", __func__);
- if (depd->offset == -1) {
- eagle_asm_dbg("%s: get from dsp requested", __func__);
- if (depd->size > 0 && depd->size <= DEPC_MAX_SIZE) {
- buf_ = buf_m = vzalloc(depd->size);
- } else {
- eagle_asm_err("%s: get size %u invalid",
- __func__, depd->size);
- return -EINVAL;
- }
- if (!buf_m) {
- eagle_asm_err("%s: out of memory", __func__);
- return -ENOMEM;
- } else if (q6asm_dts_eagle_get(ac, depd->id,
- depd->size, buf_m,
- po, mod) < 0) {
- eagle_asm_err("%s: asm get failed", __func__);
- ret = -EFAULT;
- goto DTS_EAGLE_IOCTL_GET_PARAM_PRE_EXIT;
- }
- eagle_asm_dbg("%s: get result: param id 0x%x value %d size %u",
- __func__, depd->id, *(int *)buf_m, depd->size);
- } else {
- s32 tgt = _get_cb_for_dev(depd->device);
- if (tgt < 0) {
- eagle_asm_err("%s: no cache for device %u found",
- __func__, depd->device);
- return -EINVAL;
- }
- offset = _c_bl[tgt][CBD_OFFSG] + depd->offset;
- /* check for integer overflow */
- if (offset > (UINT_MAX - depd->size))
- err = -EINVAL;
- if ((err != 0) || (offset + depd->size) > _depc_size) {
- eagle_asm_err("%s: invalid size %u and/or offset %u",
- __func__, depd->size, offset);
- return -EINVAL;
- }
- buf_ = (u32 *)&_depc[offset];
- }
- if (isALSA) {
- if (depd->size == 2) {
- *(long *)buf = (long)*(__u16 *)buf_;
- eagle_asm_dbg("%s: asm out 16 bit value %li",
- __func__, *(long *)buf);
- } else {
- s32 *pbuf = (s32 *)buf_;
- long *bufl = (long *)buf;
- for (i = 0; i < (depd->size >> 2); i++) {
- *bufl++ = (long)*pbuf++;
- eagle_asm_dbg("%s: asm out value %li",
- __func__, *(bufl-1));
- }
- }
- } else {
- memcpy(buf, buf_, depd->size);
- }
-DTS_EAGLE_IOCTL_GET_PARAM_PRE_EXIT:
- vfree(buf_m);
- return (int)ret;
- } else {
- s32 tgt = _get_cb_for_dev(depd->device);
- if (tgt < 0) {
- eagle_asm_err("%s: no cache for device %u found",
- __func__, depd->device);
- return -EINVAL;
- }
- offset = _c_bl[tgt][CBD_OFFSG] + depd->offset;
- /* check for integer overflow */
- if (offset > (UINT_MAX - depd->size))
- err = -EINVAL;
- if ((err != 0) || ((offset + depd->size) > _depc_size)) {
- eagle_asm_err("%s: invalid size %u and/or offset %u for parameter (cache is size %u)",
- __func__, depd->size, offset, _depc_size);
- return -EINVAL;
- }
- if (isALSA) {
- if (depd->size == 2) {
- *(__u16 *)&_depc[offset] = (__u16)*(long *)buf;
- eagle_asm_dbg("%s: asm in 16 bit value %li",
- __func__, *(long *)buf);
- } else {
- s32 *pbuf = (s32 *)&_depc[offset];
- long *bufl = (long *)buf;
- for (i = 0; i < (depd->size >> 2); i++) {
- *pbuf++ = (s32)*bufl++;
- eagle_asm_dbg("%s: asm in value %i",
- __func__, *(pbuf-1));
- }
- }
- } else {
- memcpy(&_depc[offset], buf, depd->size);
- }
- eagle_asm_dbg("%s: param info: param = 0x%X, size = %u, offset = %i, device = %u, cache block %i, global offset = %u, first bytes as integer = %i",
- __func__, depd->id, depd->size, depd->offset,
- depd->device,
- tgt, offset, *(int *)&_depc[offset]);
- if (q6asm_dts_eagle_set(ac, depd->id, depd->size,
- (void *)&_depc[offset], po, mod))
- eagle_asm_err("%s: q6asm_dts_eagle_set failed with id = 0x%X, size = %u, offset = %d",
- __func__, depd->id, depd->size, depd->offset);
- else
- eagle_asm_dbg("%s: q6asm_dts_eagle_set succeeded with id = 0x%X, size = %u, offset = %d",
- __func__, depd->id, depd->size, depd->offset);
- }
- return (int)ret;
-}
-
-/**
- * msm_dts_eagle_handle_adm() - Set or Get params from ADM
- * @depd: DTS Eagle Params structure used to set or get.
- * @buf: Buffer to get queried param value in NT mode.
- * @for_pre: For premix module or postmix module.
- * @get: Getting param from DSP or setting param.
- *
- * Set or Get params from modules in ADM session.
- *
- * Return: Return failure if any.
- */
-int msm_dts_eagle_handle_adm(struct dts_eagle_param_desc *depd, char *buf,
- bool for_pre, bool get)
-{
- u32 pid = _get_pid_from_dev(depd->device), cidx;
- s32 ret = 0;
-
- eagle_adm_dbg("%s: set/get adm", __func__);
-
- if (_isNTDevice(depd->device)) {
- eagle_adm_dbg("%s: NT Route detected", __func__);
- ret = msm_dts_eagle_handle_asm(depd, buf, for_pre, get,
- _getNTDeviceAC(), &_po_NT);
- if (ret < 0)
- eagle_adm_err("%s: NT Route set failed with id = 0x%X, size = %u, offset = %i, device = %u",
- __func__, depd->id, depd->size, depd->offset,
- depd->device);
- } else if (get) {
- cidx = adm_validate_and_get_port_index(pid);
- eagle_adm_dbg("%s: get from qdsp requested (port id 0x%X)",
- __func__, pid);
- if (adm_dts_eagle_get(pid, _cidx[cidx], depd->id,
- buf, depd->size) < 0) {
- eagle_adm_err("%s: get from qdsp via adm with port id 0x%X failed",
- __func__, pid);
- return -EFAULT;
- }
- } else if (_is_port_open_and_eagle(pid)) {
- cidx = adm_validate_and_get_port_index(pid);
- eagle_adm_dbg("%s: adm_dts_eagle_set called with id = 0x%X, size = %u, offset = %i, device = %u, port id = %u, copp index = %u",
- __func__, depd->id, depd->size, depd->offset,
- depd->device, pid, cidx);
- ret = adm_dts_eagle_set(pid, _cidx[cidx], depd->id,
- (void *)buf, depd->size);
- if (ret < 0)
- eagle_adm_err("%s: adm_dts_eagle_set failed", __func__);
- else
- eagle_adm_dbg("%s: adm_dts_eagle_set succeeded",
- __func__);
- } else {
- ret = -EINVAL;
- eagle_adm_dbg("%s: port id 0x%X not active or not Eagle",
- __func__, pid);
- }
- return (int)ret;
-}
-
-/**
- * msm_dts_eagle_ioctl() - ioctl handler function
- * @cmd: cmd to handle.
- * @arg: argument to the cmd.
- *
- * Handle DTS Eagle ioctl cmds.
- *
- * Return: Return failure if any.
- */
-int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg)
-{
- s32 ret = 0;
- switch (cmd) {
- case DTS_EAGLE_IOCTL_GET_CACHE_SIZE: {
- eagle_ioctl_info("%s: called with control 0x%X (get param cache size)",
- __func__, cmd);
- if (copy_to_user((void *)arg, &_depc_size,
- sizeof(_depc_size))) {
- eagle_ioctl_err("%s: error writing size", __func__);
- return -EFAULT;
- }
- break;
- }
- case DTS_EAGLE_IOCTL_SET_CACHE_SIZE: {
- u32 size = 0;
- eagle_ioctl_info("%s: called with control 0x%X (allocate param cache)",
- __func__, cmd);
- if (copy_from_user((void *)&size, (void *)arg, sizeof(size))) {
- eagle_ioctl_err("%s: error copying size (src:%pK, tgt:%pK, size:%zu)",
- __func__, (void *)arg, &size, sizeof(size));
- return -EFAULT;
- } else if (size > DEPC_MAX_SIZE) {
- eagle_ioctl_err("%s: cache size %u not allowed (min 0, max %u)",
- __func__, size, DEPC_MAX_SIZE);
- return -EINVAL;
- }
- if (_depc) {
- eagle_ioctl_dbg("%s: previous param cache of size %u freed",
- __func__, _depc_size);
- _depc_size = 0;
- vfree(_depc);
- _depc = NULL;
- }
- if (size)
- _depc = vzalloc(size);
- else
- eagle_ioctl_dbg("%s: %u bytes requested for param cache, nothing allocated",
- __func__, size);
- if (_depc) {
- eagle_ioctl_dbg("%s: %u bytes allocated for param cache",
- __func__, size);
- _depc_size = size;
- } else {
- eagle_ioctl_err("%s: error allocating param cache (vzalloc failed on %u bytes)",
- __func__, size);
- _depc_size = 0;
- return -ENOMEM;
- }
- break;
- }
- case DTS_EAGLE_IOCTL_GET_PARAM: {
- struct dts_eagle_param_desc depd;
- s32 for_pre = 0, get_from_core = 0, err = 0;
- u32 offset;
- void *buf, *buf_m = NULL;
- eagle_ioctl_info("%s: control 0x%X (get param)",
- __func__, cmd);
- if (copy_from_user((void *)&depd, (void *)arg, sizeof(depd))) {
- eagle_ioctl_err("%s: error copying dts_eagle_param_desc (src:%pK, tgt:%pK, size:%zu)",
- __func__, (void *)arg, &depd, sizeof(depd));
- return -EFAULT;
- }
- if (depd.device & DTS_EAGLE_FLAG_IOCTL_PRE) {
- eagle_ioctl_dbg("%s: using for premix", __func__);
- for_pre = 1;
- }
- if (depd.device & DTS_EAGLE_FLAG_IOCTL_GETFROMCORE) {
- eagle_ioctl_dbg("%s: 'get from core' requested",
- __func__);
- get_from_core = 1;
- depd.offset = -1;
- }
- depd.device &= DTS_EAGLE_FLAG_IOCTL_MASK;
- if (depd.offset == -1) {
- if (depd.size > 0 && depd.size <= DEPC_MAX_SIZE) {
- buf = buf_m = vzalloc(depd.size);
- } else {
- eagle_ioctl_err("%s: get size %u invalid",
- __func__, depd.size);
- return -EINVAL;
- }
- if (!buf_m) {
- eagle_ioctl_err("%s: out of memory", __func__);
- return -ENOMEM;
- }
- if (get_from_core)
- ret = core_dts_eagle_get(depd.id, depd.size,
- buf);
- else
- ret = msm_dts_eagle_handle_adm(&depd, buf,
- for_pre, true);
- } else {
- s32 cb = _get_cb_for_dev(depd.device);
- if (cb < 0) {
- eagle_ioctl_err("%s: no cache for device %u found",
- __func__, depd.device);
- return -EINVAL;
- }
- offset = _c_bl[cb][CBD_OFFSG] + depd.offset;
- /* check for integer overflow */
- if (offset > (UINT_MAX - depd.size))
- err = -EINVAL;
- if ((err != 0) ||
- ((offset + depd.size) > _depc_size)) {
- eagle_ioctl_err("%s: invalid size %u and/or offset %u",
- __func__, depd.size, offset);
- return -EINVAL;
- }
- buf = (void *)&_depc[offset];
- }
- if (ret < 0)
- eagle_ioctl_err("%s: error %i getting data", __func__,
- ret);
- else if (copy_to_user((void *)(((char *)arg)+sizeof(depd)),
- buf, depd.size)) {
- eagle_ioctl_err("%s: error copying get data", __func__);
- ret = -EFAULT;
- }
- vfree(buf_m);
- break;
- }
- case DTS_EAGLE_IOCTL_SET_PARAM: {
- struct dts_eagle_param_desc depd;
- s32 just_set_cache = 0, for_pre = 0, err = 0;
- u32 offset;
- s32 tgt;
- eagle_ioctl_info("%s: control 0x%X (set param)",
- __func__, cmd);
- if (copy_from_user((void *)&depd, (void *)arg, sizeof(depd))) {
- eagle_ioctl_err("%s: error copying dts_eagle_param_desc (src:%pK, tgt:%pK, size:%zu)",
- __func__, (void *)arg, &depd, sizeof(depd));
- return -EFAULT;
- }
- if (depd.device & DTS_EAGLE_FLAG_IOCTL_PRE) {
- eagle_ioctl_dbg("%s: using for premix", __func__);
- for_pre = 1;
- }
- if (depd.device & DTS_EAGLE_FLAG_IOCTL_JUSTSETCACHE) {
- eagle_ioctl_dbg("%s: 'just set cache' requested",
- __func__);
- just_set_cache = 1;
- }
- depd.device &= DTS_EAGLE_FLAG_IOCTL_MASK;
- tgt = _get_cb_for_dev(depd.device);
- if (tgt < 0) {
- eagle_ioctl_err("%s: no cache for device %u found",
- __func__, depd.device);
- return -EINVAL;
- }
- offset = _c_bl[tgt][CBD_OFFSG] + depd.offset;
- /* check for integer overflow */
- if (offset > (UINT_MAX - depd.size))
- err = -EINVAL;
- if ((err != 0) || ((offset + depd.size) > _depc_size)) {
- eagle_ioctl_err("%s: invalid size %u and/or offset %u for parameter (target cache block %i with offset %i, global cache is size %u)",
- __func__, depd.size, offset, tgt,
- _c_bl[tgt][CBD_OFFSG], _depc_size);
- return -EINVAL;
- }
- if (copy_from_user((void *)&_depc[offset],
- (void *)(((char *)arg)+sizeof(depd)),
- depd.size)) {
- eagle_ioctl_err("%s: error copying param to cache (src:%pK, tgt:%pK, size:%u)",
- __func__, ((char *)arg)+sizeof(depd),
- &_depc[offset], depd.size);
- return -EFAULT;
- }
- eagle_ioctl_dbg("%s: param info: param = 0x%X, size = %u, offset = %i, device = %u, cache block %i, global offset = %u, first bytes as integer = %i",
- __func__, depd.id, depd.size, depd.offset,
- depd.device, tgt, offset, *(int *)&_depc[offset]);
- if (!just_set_cache) {
- ret = msm_dts_eagle_handle_adm(&depd, &_depc[offset],
- for_pre, false);
- }
- break;
- }
- case DTS_EAGLE_IOCTL_SET_CACHE_BLOCK: {
- u32 b_[CBD_COUNT+1], *b = &b_[1], cb;
- eagle_ioctl_info("%s: with control 0x%X (set param cache block)",
- __func__, cmd);
- if (copy_from_user((void *)b_, (void *)arg, sizeof(b_))) {
- eagle_ioctl_err("%s: error copying cache block data (src:%pK, tgt:%pK, size:%zu)",
- __func__, (void *)arg, b_, sizeof(b_));
- return -EFAULT;
- }
- cb = b_[0];
- if (cb >= CB_COUNT) {
- eagle_ioctl_err("%s: cache block %u out of range (max %u)",
- __func__, cb, CB_COUNT-1);
- return -EINVAL;
- }
- eagle_ioctl_dbg("%s: cache block %i set: devices 0x%X, global offset %i, offsets 1:%u 2:%u 3:%u, cmds/sizes 0:0x%X %u 1:0x%X %u 2:0x%X %u 3:0x%X %u",
- __func__, cb, _c_bl[cb][CBD_DEV_MASK], _c_bl[cb][CBD_OFFSG],
- _c_bl[cb][CBD_OFFS1], _c_bl[cb][CBD_OFFS2],
- _c_bl[cb][CBD_OFFS3], _c_bl[cb][CBD_CMD0], _c_bl[cb][CBD_SZ0],
- _c_bl[cb][CBD_CMD1], _c_bl[cb][CBD_SZ1], _c_bl[cb][CBD_CMD2],
- _c_bl[cb][CBD_SZ2], _c_bl[cb][CBD_CMD3], _c_bl[cb][CBD_SZ3]);
- if ((b[CBD_OFFSG]+b[CBD_OFFS1]+b[CBD_SZ1]) > _depc_size ||
- (b[CBD_OFFSG]+b[CBD_OFFS2]+b[CBD_SZ2]) > _depc_size ||
- (b[CBD_OFFSG]+b[CBD_OFFS3]+b[CBD_SZ3]) > _depc_size) {
- eagle_ioctl_err("%s: cache block bounds out of range",
- __func__);
- return -EINVAL;
- }
- memcpy(_c_bl[cb], b, sizeof(_c_bl[cb]));
- break;
- }
- case DTS_EAGLE_IOCTL_SET_ACTIVE_DEVICE: {
- u32 data[2];
- eagle_ioctl_dbg("%s: with control 0x%X (set active device)",
- __func__, cmd);
- if (copy_from_user((void *)data, (void *)arg, sizeof(data))) {
- eagle_ioctl_err("%s: error copying active device data (src:%pK, tgt:%pK, size:%zu)",
- __func__, (void *)arg, data, sizeof(data));
- return -EFAULT;
- }
- if (data[1] != 0) {
- _device_primary = data[0];
- eagle_ioctl_dbg("%s: primary device %i", __func__,
- data[0]);
- } else {
- _device_all = data[0];
- eagle_ioctl_dbg("%s: all devices 0x%X", __func__,
- data[0]);
- }
- break;
- }
- case DTS_EAGLE_IOCTL_GET_LICENSE: {
- u32 target = 0, size = 0;
- s32 size_only;
- eagle_ioctl_dbg("%s: with control 0x%X (get license)",
- __func__, cmd);
- if (copy_from_user((void *)&target, (void *)arg,
- sizeof(target))) {
- eagle_ioctl_err("%s: error reading license index. (src:%pK, tgt:%pK, size:%zu)",
- __func__, (void *)arg, &target, sizeof(target));
- return -EFAULT;
- }
- size_only = target & (1<<31) ? 1 : 0;
- target &= 0x7FFFFFFF;
- if (target >= SEC_BLOB_MAX_CNT) {
- eagle_ioctl_err("%s: license index %u out of bounds (max index is %i)",
- __func__, target, SEC_BLOB_MAX_CNT);
- return -EINVAL;
- }
- if (_sec_blob[target] == NULL) {
- eagle_ioctl_err("%s: license index %u never initialized",
- __func__, target);
- return -EINVAL;
- }
- size = ((u32 *)_sec_blob[target])[0];
- if ((size == 0) || (size > SEC_BLOB_MAX_SIZE)) {
- eagle_ioctl_err("%s: license size %u for index %u invalid (min size is 1, max size is %u)",
- __func__, size, target, SEC_BLOB_MAX_SIZE);
- return -EINVAL;
- }
- if (size_only) {
- eagle_ioctl_dbg("%s: reporting size of license data only",
- __func__);
- if (copy_to_user((void *)(((char *)arg)+sizeof(target)),
- (void *)&size, sizeof(size))) {
- eagle_ioctl_err("%s: error copying license size",
- __func__);
- return -EFAULT;
- }
- } else if (copy_to_user((void *)(((char *)arg)+sizeof(target)),
- (void *)&(((s32 *)_sec_blob[target])[1]), size)) {
- eagle_ioctl_err("%s: error copying license data",
- __func__);
- return -EFAULT;
- } else
- eagle_ioctl_info("%s: license file %u bytes long from license index %u returned to user",
- __func__, size, target);
- break;
- }
- case DTS_EAGLE_IOCTL_SET_LICENSE: {
- u32 target[2] = {0, 0};
- eagle_ioctl_dbg("%s: control 0x%X (set license)", __func__,
- cmd);
- if (copy_from_user((void *)target, (void *)arg,
- sizeof(target))) {
- eagle_ioctl_err("%s: error reading license index (src:%pK, tgt:%pK, size:%zu)",
- __func__, (void *)arg, target, sizeof(target));
- return -EFAULT;
- }
- if (target[0] >= SEC_BLOB_MAX_CNT) {
- eagle_ioctl_err("%s: license index %u out of bounds (max index is %u)",
- __func__, target[0], SEC_BLOB_MAX_CNT-1);
- return -EINVAL;
- }
- if (target[1] == 0) {
- eagle_ioctl_dbg("%s: request to free license index %u",
- __func__, target[0]);
- kfree(_sec_blob[target[0]]);
- _sec_blob[target[0]] = NULL;
- break;
- }
- if ((target[1] == 0) || (target[1] >= SEC_BLOB_MAX_SIZE)) {
- eagle_ioctl_err("%s: license size %u for index %u invalid (min size is 1, max size is %u)",
- __func__, target[1], target[0],
- SEC_BLOB_MAX_SIZE);
- return -EINVAL;
- }
- if (_sec_blob[target[0]] != NULL) {
- if (((u32 *)_sec_blob[target[0]])[1] != target[1]) {
- eagle_ioctl_dbg("%s: request new size for already allocated license index %u",
- __func__, target[0]);
- kfree(_sec_blob[target[0]]);
- _sec_blob[target[0]] = NULL;
- }
- }
- eagle_ioctl_dbg("%s: allocating %u bytes for license index %u",
- __func__, target[1], target[0]);
- _sec_blob[target[0]] = kzalloc(target[1] + 4, GFP_KERNEL);
- if (!_sec_blob[target[0]]) {
- eagle_ioctl_err("%s: error allocating license index %u (kzalloc failed on %u bytes)",
- __func__, target[0], target[1]);
- return -ENOMEM;
- }
- ((u32 *)_sec_blob[target[0]])[0] = target[1];
- if (copy_from_user(
- (void *)&(((u32 *)_sec_blob[target[0]])[1]),
- (void *)(((char *)arg)+sizeof(target)),
- target[1])) {
- eagle_ioctl_err("%s: error copying license to index %u, size %u (src:%pK, tgt:%pK, size:%u)",
- __func__, target[0], target[1],
- ((char *)arg)+sizeof(target),
- &(((u32 *)_sec_blob[target[0]])[1]),
- target[1]);
- return -EFAULT;
- } else
- eagle_ioctl_info("%s: license file %u bytes long copied to index license index %u",
- __func__, target[1], target[0]);
- break;
- }
- case DTS_EAGLE_IOCTL_SEND_LICENSE: {
- u32 target = 0;
- eagle_ioctl_dbg("%s: control 0x%X (send license)", __func__,
- cmd);
- if (copy_from_user((void *)&target, (void *)arg,
- sizeof(target))) {
- eagle_ioctl_err("%s: error reading license index (src:%pK, tgt:%pK, size:%zu)",
- __func__, (void *)arg, &target, sizeof(target));
- return -EFAULT;
- }
- if (target >= SEC_BLOB_MAX_CNT) {
- eagle_ioctl_err("%s: license index %u out of bounds (max index is %i)",
- __func__, target, SEC_BLOB_MAX_CNT-1);
- return -EINVAL;
- }
- if (!_sec_blob[target] ||
- ((u32 *)_sec_blob[target])[0] == 0) {
- eagle_ioctl_err("%s: license index %u is invalid",
- __func__, target);
- return -EINVAL;
- }
- if (core_dts_eagle_set(((s32 *)_sec_blob[target])[0],
- (char *)&((s32 *)_sec_blob[target])[1]) < 0)
- eagle_ioctl_err("%s: core_dts_eagle_set failed with id = %u",
- __func__, target);
- else
- eagle_ioctl_info("%s: core_dts_eagle_set succeeded with id = %u",
- __func__, target);
- break;
- }
- case DTS_EAGLE_IOCTL_SET_VOLUME_COMMANDS: {
- s32 spec = 0;
- eagle_ioctl_info("%s: control 0x%X (set volume commands)",
- __func__, cmd);
- if (copy_from_user((void *)&spec, (void *)arg,
- sizeof(spec))) {
- eagle_ioctl_err("%s: error reading volume command specifier (src:%pK, tgt:%pK, size:%zu)",
- __func__, (void *)arg, &spec, sizeof(spec));
- return -EFAULT;
- }
- if (spec & 0x80000000) {
- u32 idx = (spec & 0x0000F000) >> 12;
- s32 size = spec & 0x00000FFF;
- eagle_ioctl_dbg("%s: setting volume command %i size: %i",
- __func__, idx, size);
- if (idx >= _vol_cmd_cnt) {
- eagle_ioctl_err("%s: volume command index %u out of bounds (only %u allocated)",
- __func__, idx, _vol_cmd_cnt);
- return -EINVAL;
- }
- if (_volume_cmds_alloc2(idx, size) < 0) {
- eagle_ioctl_err("%s: error allocating memory for volume controls",
- __func__);
- return -ENOMEM;
- }
- if (copy_from_user((void *)&_vol_cmds_d[idx],
- (void *)(((char *)arg) + sizeof(int)),
- sizeof(struct vol_cmds_d))) {
- eagle_ioctl_err("%s: error reading volume command descriptor (src:%pK, tgt:%pK, size:%zu)",
- __func__, ((char *)arg) + sizeof(int),
- &_vol_cmds_d[idx],
- sizeof(struct vol_cmds_d));
- return -EFAULT;
- }
- eagle_ioctl_dbg("%s: setting volume command %i spec (size %zu): %i %i %i %i",
- __func__, idx, sizeof(struct vol_cmds_d),
- _vol_cmds_d[idx].d[0], _vol_cmds_d[idx].d[1],
- _vol_cmds_d[idx].d[2], _vol_cmds_d[idx].d[3]);
- if (copy_from_user((void *)_vol_cmds[idx],
- (void *)(((char *)arg) + (sizeof(int) +
- sizeof(struct vol_cmds_d))), size)) {
- eagle_ioctl_err("%s: error reading volume command string (src:%pK, tgt:%pK, size:%i)",
- __func__, ((char *)arg) + (sizeof(int) +
- sizeof(struct vol_cmds_d)),
- _vol_cmds[idx], size);
- return -EFAULT;
- }
- } else {
- eagle_ioctl_dbg("%s: setting volume command size",
- __func__);
- if (spec < 0 || spec > VOL_CMD_CNT_MAX) {
- eagle_ioctl_err("%s: volume command count %i out of bounds (min 0, max %i)",
- __func__, spec, VOL_CMD_CNT_MAX);
- return -EINVAL;
- } else if (spec == 0) {
- eagle_ioctl_dbg("%s: request to free volume commands",
- __func__);
- _volume_cmds_free();
- break;
- }
- eagle_ioctl_dbg("%s: setting volume command size requested = %i",
- __func__, spec);
- if (_volume_cmds_alloc1(spec) < 0) {
- eagle_ioctl_err("%s: error allocating memory for volume controls",
- __func__);
- return -ENOMEM;
- }
- }
- break;
- }
- default: {
- eagle_ioctl_err("%s: control 0x%X (invalid control)",
- __func__, cmd);
- ret = -EINVAL;
- }
- }
- return (int)ret;
-}
-
-/**
- * msm_dts_eagle_compat_ioctl() - To handle 32bit to 64bit ioctl compatibility
- * @cmd: cmd to handle.
- * @arg: argument to the cmd.
- *
- * Handle DTS Eagle ioctl cmds from 32bit userspace.
- *
- * Return: Return failure if any.
- */
-#ifdef CONFIG_COMPAT
-int msm_dts_eagle_compat_ioctl(unsigned int cmd, unsigned long arg)
-{
- switch (cmd) {
- case DTS_EAGLE_IOCTL_GET_CACHE_SIZE32:
- cmd = DTS_EAGLE_IOCTL_GET_CACHE_SIZE;
- break;
- case DTS_EAGLE_IOCTL_SET_CACHE_SIZE32:
- cmd = DTS_EAGLE_IOCTL_SET_CACHE_SIZE;
- break;
- case DTS_EAGLE_IOCTL_GET_PARAM32:
- cmd = DTS_EAGLE_IOCTL_GET_PARAM;
- break;
- case DTS_EAGLE_IOCTL_SET_PARAM32:
- cmd = DTS_EAGLE_IOCTL_SET_PARAM;
- break;
- case DTS_EAGLE_IOCTL_SET_CACHE_BLOCK32:
- cmd = DTS_EAGLE_IOCTL_SET_CACHE_BLOCK;
- break;
- case DTS_EAGLE_IOCTL_SET_ACTIVE_DEVICE32:
- cmd = DTS_EAGLE_IOCTL_SET_ACTIVE_DEVICE;
- break;
- case DTS_EAGLE_IOCTL_GET_LICENSE32:
- cmd = DTS_EAGLE_IOCTL_GET_LICENSE;
- break;
- case DTS_EAGLE_IOCTL_SET_LICENSE32:
- cmd = DTS_EAGLE_IOCTL_SET_LICENSE;
- break;
- case DTS_EAGLE_IOCTL_SEND_LICENSE32:
- cmd = DTS_EAGLE_IOCTL_SEND_LICENSE;
- break;
- case DTS_EAGLE_IOCTL_SET_VOLUME_COMMANDS32:
- cmd = DTS_EAGLE_IOCTL_SET_VOLUME_COMMANDS;
- break;
- default:
- break;
- }
- return msm_dts_eagle_ioctl(cmd, arg);
-}
-#endif
-/**
- * msm_dts_eagle_init_pre() - Initialize DTS premix module
- * @ac: Initialize premix module in the ASM session.
- *
- * Initialize DTS premix module on provided ASM session
- *
- * Return: Return failure if any.
- */
-int msm_dts_eagle_init_pre(struct audio_client *ac)
-{
- return msm_dts_eagle_enable_asm(ac, _is_hpx_enabled,
- AUDPROC_MODULE_ID_DTS_HPX_PREMIX);
-}
-
-/**
- * msm_dts_eagle_deinit_pre() - Deinitialize DTS premix module
- * @ac: Deinitialize premix module in the ASM session.
- *
- * Deinitialize DTS premix module on provided ASM session
- *
- * Return: Currently does nothing so 0.
- */
-int msm_dts_eagle_deinit_pre(struct audio_client *ac)
-{
- return 0;
-}
-
-/**
- * msm_dts_eagle_init_post() - Initialize DTS postmix module
- * @port_id: Port id for the ADM session.
- * @copp_idx: Copp idx for the ADM session.
- *
- * Initialize DTS postmix module on ADM session
- *
- * Return: Return failure if any.
- */
-int msm_dts_eagle_init_post(int port_id, int copp_idx)
-{
- return msm_dts_eagle_enable_adm(port_id, copp_idx, _is_hpx_enabled);
-}
-
-/**
- * msm_dts_eagle_deinit_post() - Deinitialize DTS postmix module
- * @port_id: Port id for the ADM session.
- * @topology: Topology in use.
- *
- * Deinitialize DTS postmix module on ADM session
- *
- * Return: Currently does nothing so 0.
- */
-int msm_dts_eagle_deinit_post(int port_id, int topology)
-{
- return 0;
-}
-
-/**
- * msm_dts_eagle_init_master_module() - Initialize both DTS modules
- * @ac: Initialize modules in the ASM session.
- *
- * Initialize DTS modules on ASM session
- *
- * Return: Success.
- */
-int msm_dts_eagle_init_master_module(struct audio_client *ac)
-{
- _set_audioclient(ac);
- msm_dts_eagle_enable_asm(ac, _is_hpx_enabled,
- AUDPROC_MODULE_ID_DTS_HPX_PREMIX);
- msm_dts_eagle_enable_asm(ac, _is_hpx_enabled,
- AUDPROC_MODULE_ID_DTS_HPX_POSTMIX);
- return 0;
-}
-
-/**
- * msm_dts_eagle_deinit_master_module() - Deinitialize both DTS modules
- * @ac: Deinitialize modules in the ASM session.
- *
- * Deinitialize DTS modules on ASM session
- *
- * Return: Success.
- */
-int msm_dts_eagle_deinit_master_module(struct audio_client *ac)
-{
- msm_dts_eagle_deinit_pre(ac);
- msm_dts_eagle_deinit_post(-1, 0);
- _clear_audioclient();
- return 0;
-}
-
-/**
- * msm_dts_eagle_is_hpx_on() - Check if HPX effects are On
- *
- * Check if HPX effects are On
- *
- * Return: On/Off.
- */
-int msm_dts_eagle_is_hpx_on(void)
-{
- return _is_hpx_enabled;
-}
-
-/**
- * msm_dts_eagle_pcm_new() - Create hwdep node
- * @runtime: snd_soc_pcm_runtime structure.
- *
- * Create hwdep node
- *
- * Return: Success.
- */
-int msm_dts_eagle_pcm_new(struct snd_soc_pcm_runtime *runtime)
-{
- if (!_ref_cnt++) {
- _init_cb_descs();
- _reg_ion_mem();
- }
- return 0;
-}
-
-/**
- * msm_dts_eagle_pcm_free() - remove hwdep node
- * @runtime: snd_soc_pcm_runtime structure.
- *
- * Remove hwdep node
- *
- * Return: void.
- */
-void msm_dts_eagle_pcm_free(struct snd_pcm *pcm)
-{
- if (!--_ref_cnt)
- _unreg_ion_mem();
- vfree(_depc);
-}
-
-MODULE_DESCRIPTION("DTS EAGLE platform driver");
-MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.c b/sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.c
index 7c35d19bb61..8fc49b29000 100644
--- a/sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.c
+++ b/sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2012-2014, 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 2016-2017, The Linux Foundation. All
+ * rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -19,7 +20,6 @@
#include <sound/control.h>
#include <sound/q6adm-v2.h>
#include <sound/asound.h>
-#include <sound/msm-dts-eagle.h>
#include "msm-dts-srs-tm-config.h"
#include "msm-pcm-routing-v2.h"
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-devdep.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-devdep.c
index e80b6fb9cf8..fb44bb71043 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-devdep.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-devdep.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014, 2017 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -14,8 +14,6 @@
#include <linux/module.h>
#include <sound/hwdep.h>
#include <sound/devdep_params.h>
-#include <sound/msm-dts-eagle.h>
-
#include "msm-pcm-routing-devdep.h"
#include "msm-ds2-dap-config.h"
@@ -53,23 +51,6 @@ static int msm_pcm_routing_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
case SNDRV_DEVDEP_DAP_IOCTL_GET_VISUALIZER:
ret = msm_ds2_dap_ioctl(hw, file, cmd, argp);
break;
- case DTS_EAGLE_IOCTL_GET_CACHE_SIZE:
- case DTS_EAGLE_IOCTL_SET_CACHE_SIZE:
- case DTS_EAGLE_IOCTL_GET_PARAM:
- case DTS_EAGLE_IOCTL_SET_PARAM:
- case DTS_EAGLE_IOCTL_SET_CACHE_BLOCK:
- case DTS_EAGLE_IOCTL_SET_ACTIVE_DEVICE:
- case DTS_EAGLE_IOCTL_GET_LICENSE:
- case DTS_EAGLE_IOCTL_SET_LICENSE:
- case DTS_EAGLE_IOCTL_SEND_LICENSE:
- case DTS_EAGLE_IOCTL_SET_VOLUME_COMMANDS:
- ret = msm_dts_eagle_ioctl(cmd, arg);
- if (ret == -EPERM) {
- pr_err("%s called with invalid control 0x%X\n",
- __func__, cmd);
- ret = -EINVAL;
- }
- break;
default:
pr_err("%s called with invalid control 0x%X\n", __func__, cmd);
ret = -EINVAL;
@@ -81,7 +62,6 @@ static int msm_pcm_routing_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
void msm_pcm_routing_hwdep_free(struct snd_pcm *pcm)
{
pr_debug("%s\n", __func__);
- msm_dts_eagle_pcm_free(pcm);
}
#ifdef CONFIG_COMPAT
@@ -105,23 +85,6 @@ static int msm_pcm_routing_hwdep_compat_ioctl(struct snd_hwdep *hw,
case SNDRV_DEVDEP_DAP_IOCTL_GET_VISUALIZER32:
ret = msm_ds2_dap_compat_ioctl(hw, file, cmd, argp);
break;
- case DTS_EAGLE_IOCTL_GET_CACHE_SIZE32:
- case DTS_EAGLE_IOCTL_SET_CACHE_SIZE32:
- case DTS_EAGLE_IOCTL_GET_PARAM32:
- case DTS_EAGLE_IOCTL_SET_PARAM32:
- case DTS_EAGLE_IOCTL_SET_CACHE_BLOCK32:
- case DTS_EAGLE_IOCTL_SET_ACTIVE_DEVICE32:
- case DTS_EAGLE_IOCTL_GET_LICENSE32:
- case DTS_EAGLE_IOCTL_SET_LICENSE32:
- case DTS_EAGLE_IOCTL_SEND_LICENSE32:
- case DTS_EAGLE_IOCTL_SET_VOLUME_COMMANDS32:
- ret = msm_dts_eagle_compat_ioctl(cmd, arg);
- if (ret == -EPERM) {
- pr_err("%s called with invalid control 0x%X\n",
- __func__, cmd);
- ret = -EINVAL;
- }
- break;
default:
pr_err("%s called with invalid control 0x%X\n", __func__, cmd);
ret = -EINVAL;
@@ -167,7 +130,7 @@ int msm_pcm_routing_hwdep_new(struct snd_soc_pcm_runtime *runtime,
#ifdef CONFIG_COMPAT
hwdep->ops.ioctl_compat = msm_pcm_routing_hwdep_compat_ioctl;
#endif
- return msm_dts_eagle_pcm_new(runtime);
+ return rc;
}
#endif
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index f3d1d6e2c7a..1e129c58645 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -33,7 +33,6 @@
#include <sound/pcm_params.h>
#include <sound/q6core.h>
#include <sound/audio_cal_utils.h>
-#include <sound/msm-dts-eagle.h>
#include <sound/audio_effects.h>
#include <sound/hwdep.h>
@@ -155,10 +154,6 @@ static void msm_pcm_routing_cfg_pp(int port_id, int copp_idx, int topology,
__func__, topology, port_id, rc);
}
break;
- case ADM_CMD_COPP_OPEN_TOPOLOGY_ID_DTS_HPX:
- pr_debug("%s: DTS_EAGLE_COPP_TOPOLOGY_ID\n", __func__);
- msm_dts_eagle_init_post(port_id, copp_idx);
- break;
case ADM_CMD_COPP_OPEN_TOPOLOGY_ID_AUDIOSPHERE:
pr_debug("%s: TOPOLOGY_ID_AUDIOSPHERE\n", __func__);
msm_qti_pp_asphere_init(port_id, copp_idx);
@@ -190,10 +185,6 @@ static void msm_pcm_routing_deinit_pp(int port_id, int topology)
msm_dolby_dap_deinit(port_id);
}
break;
- case ADM_CMD_COPP_OPEN_TOPOLOGY_ID_DTS_HPX:
- pr_debug("%s: DTS_EAGLE_COPP_TOPOLOGY_ID\n", __func__);
- msm_dts_eagle_deinit_post(port_id, topology);
- break;
case ADM_CMD_COPP_OPEN_TOPOLOGY_ID_AUDIOSPHERE:
pr_debug("%s: TOPOLOGY_ID_AUDIOSPHERE\n", __func__);
msm_qti_pp_asphere_deinit(port_id);
@@ -6653,8 +6644,6 @@ static int msm_routing_probe(struct snd_soc_platform *platform)
device_pp_params_mixer_controls,
ARRAY_SIZE(device_pp_params_mixer_controls));
- msm_dts_eagle_add_controls(platform);
-
snd_soc_add_platform_controls(platform, msm_source_tracking_controls,
ARRAY_SIZE(msm_source_tracking_controls));
diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c
index e83c9c7d55e..1427e24a7f4 100644
--- a/sound/soc/msm/qdsp6v2/q6adm.c
+++ b/sound/soc/msm/qdsp6v2/q6adm.c
@@ -24,7 +24,6 @@
#include <sound/q6afe-v2.h>
#include <sound/audio_cal_utils.h>
#include <sound/asound.h>
-#include <sound/msm-dts-eagle.h>
#include "msm-dts-srs-tm-config.h"
#include <sound/adsp_err.h>
@@ -250,222 +249,6 @@ static int adm_get_next_available_copp(int port_idx)
return idx;
}
-int adm_dts_eagle_set(int port_id, int copp_idx, int param_id,
- void *data, uint32_t size)
-{
- struct adm_cmd_set_pp_params_v5 admp;
- int p_idx, ret = 0, *ob_params;
-
- pr_debug("DTS_EAGLE_ADM: %s - port id %i, copp idx %i, param id 0x%X size %u\n",
- __func__, port_id, copp_idx, param_id, size);
-
- port_id = afe_convert_virtual_to_portid(port_id);
- p_idx = adm_validate_and_get_port_index(port_id);
- pr_debug("DTS_EAGLE_ADM: %s - after lookup, port id %i, port idx %i\n",
- __func__, port_id, p_idx);
-
- if (p_idx < 0) {
- pr_err("DTS_EAGLE_ADM: %s: invalid port index 0x%x, port id 0x%x\n",
- __func__, p_idx, port_id);
- return -EINVAL;
- }
-
- if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) {
- pr_err("DTS_EAGLE_ADM: %s: Invalid copp_idx: %d\n", __func__,
- copp_idx);
- return -EINVAL;
- }
-
- ob_params = (int *)this_adm.outband_memmap.kvaddr;
- if (ob_params == NULL) {
- pr_err("DTS_EAGLE_ADM: %s - NULL memmap. Non Eagle topology selected?\n",
- __func__);
- ret = -EINVAL;
- goto fail_cmd;
- }
- /* check for integer overflow */
- if (size > (UINT_MAX - APR_CMD_OB_HDR_SZ))
- ret = -EINVAL;
- if ((ret < 0) ||
- (size + APR_CMD_OB_HDR_SZ > this_adm.outband_memmap.size)) {
- pr_err("DTS_EAGLE_ADM - %s: ion alloc of size %zu too small for size requested %u\n",
- __func__, this_adm.outband_memmap.size,
- size + APR_CMD_OB_HDR_SZ);
- ret = -EINVAL;
- goto fail_cmd;
- }
- *ob_params++ = AUDPROC_MODULE_ID_DTS_HPX_POSTMIX;
- *ob_params++ = param_id;
- *ob_params++ = size;
- memcpy(ob_params, data, size);
-
- admp.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- admp.hdr.pkt_size = sizeof(admp);
- admp.hdr.src_svc = APR_SVC_ADM;
- admp.hdr.src_domain = APR_DOMAIN_APPS;
- admp.hdr.src_port = port_id;
- admp.hdr.dest_svc = APR_SVC_ADM;
- admp.hdr.dest_domain = APR_DOMAIN_ADSP;
- admp.hdr.dest_port = atomic_read(&this_adm.copp.id[p_idx][copp_idx]);
- admp.hdr.token = p_idx << 16 | copp_idx;
- admp.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5;
- admp.payload_addr_lsw = lower_32_bits(this_adm.outband_memmap.paddr);
- admp.payload_addr_msw = populate_upper_32_bits(
- this_adm.outband_memmap.paddr);
- admp.mem_map_handle = atomic_read(&this_adm.mem_map_handles[
- ADM_DTS_EAGLE]);
- admp.payload_size = size + sizeof(struct adm_param_data_v5);
-
- pr_debug("DTS_EAGLE_ADM: %s - Command was sent now check Q6 - port id = %d, size %d, module id %x, param id %x.\n",
- __func__, admp.hdr.dest_port,
- admp.payload_size, AUDPROC_MODULE_ID_DTS_HPX_POSTMIX,
- param_id);
- atomic_set(&this_adm.copp.stat[p_idx][copp_idx], 0);
- atomic_set(&this_adm.copp.cmd_err_code[p_idx][copp_idx], 0);
- ret = apr_send_pkt(this_adm.apr, (uint32_t *)&admp);
- if (ret < 0) {
- pr_err("DTS_EAGLE_ADM: %s - ADM enable for port %d failed\n",
- __func__, port_id);
- ret = -EINVAL;
- goto fail_cmd;
- }
- ret = wait_event_timeout(this_adm.copp.wait[p_idx][copp_idx],
- atomic_read(&this_adm.copp.stat[p_idx][copp_idx]),
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("DTS_EAGLE_ADM: %s - set params timed out port = %d\n",
- __func__, port_id);
- ret = -EINVAL;
- } else if (atomic_read(&this_adm.copp.cmd_err_code
- [p_idx][copp_idx]) > 0) {
- pr_err("%s: DSP returned error[%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_adm.copp.cmd_err_code
- [p_idx][copp_idx])));
- ret = adsp_err_get_lnx_err_code(
- atomic_read(&this_adm.copp.cmd_err_code
- [p_idx][copp_idx]));
- } else {
- ret = 0;
- }
-
-fail_cmd:
- return ret;
-}
-
-int adm_dts_eagle_get(int port_id, int copp_idx, int param_id,
- void *data, uint32_t size)
-{
- struct adm_cmd_get_pp_params_v5 admp;
- int p_idx, ret = 0, *ob_params;
- uint32_t orig_size = size;
- pr_debug("DTS_EAGLE_ADM: %s - port id %i, copp idx %i, param id 0x%X\n",
- __func__, port_id, copp_idx, param_id);
-
- port_id = afe_convert_virtual_to_portid(port_id);
- p_idx = adm_validate_and_get_port_index(port_id);
- if (p_idx < 0) {
- pr_err("DTS_EAGLE_ADM: %s - invalid port index %i, port id %i, copp idx %i\n",
- __func__, p_idx, port_id, copp_idx);
- return -EINVAL;
- }
-
- if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) {
- pr_err("DTS_EAGLE_ADM: %s: Invalid copp_idx: %d\n", __func__,
- copp_idx);
- return -EINVAL;
- }
-
- if ((size == 0) || !data) {
- pr_err("DTS_EAGLE_ADM: %s - invalid size %u or pointer %pK.\n",
- __func__, size, data);
- return -EINVAL;
- }
-
- size = (size+3) & 0xFFFFFFFC;
-
- ob_params = (int *)(this_adm.outband_memmap.kvaddr);
- if (ob_params == NULL) {
- pr_err("DTS_EAGLE_ADM: %s - NULL memmap. Non Eagle topology selected?",
- __func__);
- ret = -EINVAL;
- goto fail_cmd;
- }
- /* check for integer overflow */
- if (size > (UINT_MAX - APR_CMD_OB_HDR_SZ))
- ret = -EINVAL;
- if ((ret < 0) ||
- (size + APR_CMD_OB_HDR_SZ > this_adm.outband_memmap.size)) {
- pr_err("DTS_EAGLE_ADM - %s: ion alloc of size %zu too small for size requested %u\n",
- __func__, this_adm.outband_memmap.size,
- size + APR_CMD_OB_HDR_SZ);
- ret = -EINVAL;
- goto fail_cmd;
- }
- *ob_params++ = AUDPROC_MODULE_ID_DTS_HPX_POSTMIX;
- *ob_params++ = param_id;
- *ob_params++ = size;
-
- admp.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- admp.hdr.pkt_size = sizeof(admp);
- admp.hdr.src_svc = APR_SVC_ADM;
- admp.hdr.src_domain = APR_DOMAIN_APPS;
- admp.hdr.src_port = port_id;
- admp.hdr.dest_svc = APR_SVC_ADM;
- admp.hdr.dest_domain = APR_DOMAIN_ADSP;
- admp.hdr.dest_port = atomic_read(&this_adm.copp.id[p_idx][copp_idx]);
- admp.hdr.token = p_idx << 16 | copp_idx;
- admp.hdr.opcode = ADM_CMD_GET_PP_PARAMS_V5;
- admp.data_payload_addr_lsw =
- lower_32_bits(this_adm.outband_memmap.paddr);
- admp.data_payload_addr_msw =
- populate_upper_32_bits(
- this_adm.outband_memmap.paddr);
- admp.mem_map_handle = atomic_read(&this_adm.mem_map_handles[
- ADM_DTS_EAGLE]);
- admp.module_id = AUDPROC_MODULE_ID_DTS_HPX_POSTMIX;
- admp.param_id = param_id;
- admp.param_max_size = size + sizeof(struct adm_param_data_v5);
- admp.reserved = 0;
-
- atomic_set(&this_adm.copp.stat[p_idx][copp_idx], 0);
- atomic_set(&this_adm.copp.cmd_err_code[p_idx][copp_idx], 0);
-
- ret = apr_send_pkt(this_adm.apr, (uint32_t *)&admp);
- if (ret < 0) {
- pr_err("DTS_EAGLE_ADM: %s - Failed to get EAGLE Params on port %d\n",
- __func__, port_id);
- ret = -EINVAL;
- goto fail_cmd;
- }
- ret = wait_event_timeout(this_adm.copp.wait[p_idx][copp_idx],
- atomic_read(&this_adm.copp.stat[p_idx][copp_idx]),
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("DTS_EAGLE_ADM: %s - EAGLE get params timed out port = %d\n",
- __func__, port_id);
- ret = -EINVAL;
- goto fail_cmd;
- } else if (atomic_read(&this_adm.copp.cmd_err_code
- [p_idx][copp_idx]) > 0) {
- pr_err("%s: DSP returned error[%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_adm.copp.cmd_err_code
- [p_idx][copp_idx])));
- ret = adsp_err_get_lnx_err_code(
- atomic_read(&this_adm.copp.cmd_err_code
- [p_idx][copp_idx]));
- goto fail_cmd;
- }
-
- memcpy(data, ob_params, orig_size);
- ret = 0;
-fail_cmd:
- return ret;
-}
-
int srs_trumedia_open(int port_id, int copp_idx, __s32 srs_tech_id,
void *srs_params)
{
@@ -2265,13 +2048,6 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology,
__func__, port_id, path, rate, channel_mode, perf_mode,
topology);
- /* For DTS EAGLE only, force 24 bit */
- if ((topology == ADM_CMD_COPP_OPEN_TOPOLOGY_ID_DTS_HPX) &&
- (perf_mode == LEGACY_PCM_MODE)) {
- bit_width = 24;
- pr_debug("%s: Force open adm in 24-bit for DTS HPX topology 0x%x\n",
- __func__, topology);
- }
port_id = q6audio_convert_virtual_to_portid(port_id);
port_idx = adm_validate_and_get_port_index(port_id);
if (port_idx < 0) {
@@ -2298,8 +2074,7 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology,
flags = ADM_LOW_LATENCY_DEVICE_SESSION;
if ((topology == DOLBY_ADM_COPP_TOPOLOGY_ID) ||
(topology == DS2_ADM_COPP_TOPOLOGY_ID) ||
- (topology == SRS_TRUMEDIA_TOPOLOGY_ID) ||
- (topology == ADM_CMD_COPP_OPEN_TOPOLOGY_ID_DTS_HPX))
+ (topology == SRS_TRUMEDIA_TOPOLOGY_ID))
topology = DEFAULT_COPP_TOPOLOGY;
} else {
if (path == ADM_PATH_COMPRESSED_RX)
@@ -2368,20 +2143,6 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology,
(uint32_t)this_adm.outband_memmap.size);
}
}
- if ((topology == ADM_CMD_COPP_OPEN_TOPOLOGY_ID_DTS_HPX) &&
- (perf_mode == LEGACY_PCM_MODE)) {
- int res = 0;
- atomic_set(&this_adm.mem_map_index, ADM_DTS_EAGLE);
- msm_dts_ion_memmap(&this_adm.outband_memmap);
- res = adm_memory_map_regions(
- &this_adm.outband_memmap.paddr,
- 0,
- (uint32_t *)&this_adm.outband_memmap.size,
- 1);
- if (res < 0)
- pr_err("%s: DTS_EAGLE mmap did not work!",
- __func__);
- }
open.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
APR_HDR_LEN(APR_HDR_SIZE),
APR_PKT_VER);
@@ -2661,21 +2422,6 @@ int adm_close(int port_id, int perf_mode, int copp_idx)
}
}
- if ((perf_mode == LEGACY_PCM_MODE) &&
- (this_adm.outband_memmap.paddr != 0) &&
- (atomic_read(
- &this_adm.copp.topology[port_idx][copp_idx]) ==
- ADM_CMD_COPP_OPEN_TOPOLOGY_ID_DTS_HPX)) {
- atomic_set(&this_adm.mem_map_index, ADM_DTS_EAGLE);
- ret = adm_memory_unmap_regions();
- if (ret < 0) {
- pr_err("%s: adm mem unmmap err %d",
- __func__, ret);
- } else {
- atomic_set(&this_adm.mem_map_handles
- [ADM_DTS_EAGLE], 0);
- }
- }
if ((afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_TX) &&
(this_adm.sourceTrackingData.memmap.paddr != 0)) {
@@ -3062,10 +2808,6 @@ static int adm_init_cal_data(void)
{NULL, NULL, NULL, NULL, NULL, NULL} },
{NULL, NULL, cal_utils_match_buf_num} },
- {{DTS_EAGLE_CAL_TYPE,
- {NULL, NULL, NULL, NULL, NULL, NULL} },
- {NULL, NULL, cal_utils_match_buf_num} },
-
{{SRS_TRUMEDIA_CAL_TYPE,
{NULL, NULL, NULL, NULL, NULL, NULL} },
{NULL, NULL, cal_utils_match_buf_num} }
diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c
index 21a0edf68f4..084cde4bf55 100644
--- a/sound/soc/msm/qdsp6v2/q6afe.c
+++ b/sound/soc/msm/qdsp6v2/q6afe.c
@@ -1015,7 +1015,7 @@ static int afe_get_cal_topology_id(u16 port_id, u32 *topology_id)
struct audio_cal_info_afe_top *afe_top_info = NULL;
if (this_afe.cal_data[AFE_TOPOLOGY_CAL] == NULL) {
- pr_debug("%s: [AFE_TOPOLOGY_CAL] not initialized\n", __func__);
+ pr_err("%s: [AFE_TOPOLOGY_CAL] not initialized\n", __func__);
return -EINVAL;
}
if (topology_id == NULL) {
@@ -1028,7 +1028,7 @@ static int afe_get_cal_topology_id(u16 port_id, u32 *topology_id)
cal_block = afe_find_cal_topo_id_by_port(
this_afe.cal_data[AFE_TOPOLOGY_CAL], port_id);
if (cal_block == NULL) {
- pr_debug("%s: [AFE_TOPOLOGY_CAL] not initialized for this port %d\n",
+ pr_err("%s: [AFE_TOPOLOGY_CAL] not initialized for this port %d\n",
__func__, port_id);
ret = -EINVAL;
goto unlock;
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 7246c944c8a..d7fb514f309 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
@@ -41,8 +41,8 @@
#include <sound/q6core.h>
#include <sound/q6audio-v2.h>
#include <sound/audio_cal_utils.h>
-#include <sound/msm-dts-eagle.h>
#include <sound/adsp_err.h>
+#include <sound/compress_params.h>
#define TRUE 0x01
#define FALSE 0x00
@@ -2147,9 +2147,6 @@ static int __q6asm_open_read(struct audio_client *ac,
open.src_endpointype = ASM_END_POINT_DEVICE_MATRIX;
open.preprocopo_id = q6asm_get_asm_topology();
- if ((open.preprocopo_id == ASM_STREAM_POSTPROC_TOPO_ID_DTS_HPX) ||
- (open.preprocopo_id == ASM_STREAM_POSTPROC_TOPO_ID_HPX_PLUS))
- open.preprocopo_id = ASM_STREAM_POSTPROCOPO_ID_NONE;
open.bits_per_sample = bits_per_sample;
open.mode_flags = 0x0;
@@ -2387,16 +2384,9 @@ static int __q6asm_open_write(struct audio_client *ac, uint32_t format,
open.bits_per_sample = bits_per_sample;
open.postprocopo_id = q6asm_get_asm_topology();
- if ((ac->perf_mode != LEGACY_PCM_MODE) &&
- ((open.postprocopo_id == ASM_STREAM_POSTPROC_TOPO_ID_DTS_HPX) ||
- (open.postprocopo_id == ASM_STREAM_POSTPROC_TOPO_ID_HPX_PLUS)))
+ if (ac->perf_mode != LEGACY_PCM_MODE)
open.postprocopo_id = ASM_STREAM_POSTPROCOPO_ID_NONE;
- /* For DTS EAGLE only, force 24 bit */
- if ((open.postprocopo_id == ASM_STREAM_POSTPROC_TOPO_ID_DTS_HPX) ||
- (open.postprocopo_id == ASM_STREAM_POSTPROC_TOPO_ID_HPX_PLUS))
- open.bits_per_sample = 24;
-
pr_debug("%s: perf_mode %d asm_topology 0x%x bps %d\n", __func__,
ac->perf_mode, open.postprocopo_id, open.bits_per_sample);
@@ -2596,10 +2586,6 @@ static int __q6asm_open_read_write(struct audio_client *ac, uint32_t rd_format,
topology : open.postprocopo_id;
ac->topology = open.postprocopo_id;
- /* For DTS EAGLE only, force 24 bit */
- if ((open.postprocopo_id == ASM_STREAM_POSTPROC_TOPO_ID_DTS_HPX) ||
- (open.postprocopo_id == ASM_STREAM_POSTPROC_TOPO_ID_HPX_MASTER))
- open.bits_per_sample = 24;
switch (wr_format) {
case FORMAT_LINEAR_PCM:
@@ -5499,215 +5485,6 @@ fail_cmd:
return rc;
}
-int q6asm_dts_eagle_set(struct audio_client *ac, int param_id, uint32_t size,
- void *data, struct param_outband *po, int m_id)
-{
- int rc = 0, *ob_params = NULL;
- uint32_t sz = sizeof(struct asm_dts_eagle_param) + (po ? 0 : size);
- struct asm_dts_eagle_param *ad;
-
- if (!ac || ac->apr == NULL || (size == 0) || !data) {
- pr_err("DTS_EAGLE_ASM - %s: APR handle NULL, invalid size %u or pointer %pK.\n",
- __func__, size, data);
- return -EINVAL;
- }
-
- ad = kzalloc(sz, GFP_KERNEL);
- if (!ad) {
- pr_err("DTS_EAGLE_ASM - %s: error allocating mem of size %u\n",
- __func__, sz);
- return -ENOMEM;
- }
- pr_debug("DTS_EAGLE_ASM - %s: ac %pK param_id 0x%x size %u data %pK m_id 0x%x\n",
- __func__, ac, param_id, size, data, m_id);
- q6asm_add_hdr_async(ac, &ad->hdr, sz, 1);
- ad->hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2;
- ad->param.data_payload_addr_lsw = 0;
- ad->param.data_payload_addr_msw = 0;
-
- ad->param.mem_map_handle = 0;
- ad->param.data_payload_size = size +
- sizeof(struct asm_stream_param_data_v2);
- ad->data.module_id = m_id;
- ad->data.param_id = param_id;
- ad->data.param_size = size;
- ad->data.reserved = 0;
- atomic_set(&ac->cmd_state, 1);
-
- if (po) {
- struct list_head *ptr, *next;
- struct asm_buffer_node *node;
- pr_debug("DTS_EAGLE_ASM - %s: using out of band memory (virtual %pK, physical %pK)\n",
- __func__, po->kvaddr, &po->paddr);
- ad->param.data_payload_addr_lsw = lower_32_bits(po->paddr);
- ad->param.data_payload_addr_msw = populate_upper_32_bits(
- po->paddr);
- list_for_each_safe(ptr, next, &ac->port[IN].mem_map_handle) {
- node = list_entry(ptr, struct asm_buffer_node, list);
- if (node->buf_phys_addr == po->paddr) {
- ad->param.mem_map_handle = node->mmap_hdl;
- break;
- }
- }
- if (ad->param.mem_map_handle == 0) {
- pr_err("DTS_EAGLE_ASM - %s: mem map handle not found\n",
- __func__);
- rc = -EINVAL;
- goto fail_cmd;
- }
- /* check for integer overflow */
- if (size > (UINT_MAX - APR_CMD_OB_HDR_SZ))
- rc = -EINVAL;
- if ((rc < 0) || (size + APR_CMD_OB_HDR_SZ > po->size)) {
- pr_err("DTS_EAGLE_ASM - %s: ion alloc of size %zu too small for size requested %u\n",
- __func__, po->size, size + APR_CMD_OB_HDR_SZ);
- rc = -EINVAL;
- goto fail_cmd;
- }
- ob_params = (int *)po->kvaddr;
- *ob_params++ = m_id;
- *ob_params++ = param_id;
- *ob_params++ = size;
- memcpy(ob_params, data, size);
- } else {
- pr_debug("DTS_EAGLE_ASM - %s: using in band\n", __func__);
- memcpy(((char *)ad) + sizeof(struct asm_dts_eagle_param),
- data, size);
- }
- rc = apr_send_pkt(ac->apr, (uint32_t *)ad);
- if (rc < 0) {
- pr_err("DTS_EAGLE_ASM - %s: set-params send failed paramid[0x%x]\n",
- __func__, ad->data.param_id);
- rc = -EINVAL;
- goto fail_cmd;
- }
-
- rc = wait_event_timeout(ac->cmd_wait,
- (atomic_read(&ac->cmd_state) <= 0), 1*HZ);
- if (!rc) {
- pr_err("DTS_EAGLE_ASM - %s: timeout, set-params paramid[0x%x]\n",
- __func__, ad->data.param_id);
- rc = -EINVAL;
- goto fail_cmd;
- }
- rc = 0;
-fail_cmd:
- kfree(ad);
- return rc;
-}
-
-int q6asm_dts_eagle_get(struct audio_client *ac, int param_id, uint32_t size,
- void *data, struct param_outband *po, int m_id)
-{
- struct asm_dts_eagle_param_get *ad;
- int rc = 0, *ob_params = NULL;
- uint32_t sz = sizeof(struct asm_dts_eagle_param) + APR_CMD_GET_HDR_SZ +
- (po ? 0 : size);
-
- if (!ac || ac->apr == NULL || (size == 0) || !data) {
- pr_err("DTS_EAGLE_ASM - %s: APR handle NULL, invalid size %u or pointer %pK\n",
- __func__, size, data);
- return -EINVAL;
- }
- ad = kzalloc(sz, GFP_KERNEL);
- if (!ad) {
- pr_err("DTS_EAGLE_ASM - %s: error allocating memory of size %u\n",
- __func__, sz);
- return -ENOMEM;
- }
- pr_debug("DTS_EAGLE_ASM - %s: ac %pK param_id 0x%x size %u data %pK m_id 0x%x\n",
- __func__, ac, param_id, size, data, m_id);
- q6asm_add_hdr(ac, &ad->hdr, sz, TRUE);
- ad->hdr.opcode = ASM_STREAM_CMD_GET_PP_PARAMS_V2;
- ad->param.data_payload_addr_lsw = 0;
- ad->param.data_payload_addr_msw = 0;
- ad->param.mem_map_handle = 0;
- ad->param.module_id = m_id;
- ad->param.param_id = param_id;
- ad->param.param_max_size = size + APR_CMD_GET_HDR_SZ;
- ad->param.reserved = 0;
- atomic_set(&ac->cmd_state, 1);
-
- generic_get_data = kzalloc(size + sizeof(struct generic_get_data_),
- GFP_KERNEL);
- if (!generic_get_data) {
- pr_err("DTS_EAGLE_ASM - %s: error allocating mem of size %u\n",
- __func__, size);
- rc = -ENOMEM;
- goto fail_cmd;
- }
-
- if (po) {
- struct list_head *ptr, *next;
- struct asm_buffer_node *node;
- pr_debug("DTS_EAGLE_ASM - %s: using out of band memory (virtual %pK, physical %pK)\n",
- __func__, po->kvaddr, &po->paddr);
- ad->param.data_payload_addr_lsw = lower_32_bits(po->paddr);
- ad->param.data_payload_addr_msw = populate_upper_32_bits(
- po->paddr);
- list_for_each_safe(ptr, next, &ac->port[IN].mem_map_handle) {
- node = list_entry(ptr, struct asm_buffer_node, list);
- if (node->buf_phys_addr == po->paddr) {
- ad->param.mem_map_handle = node->mmap_hdl;
- break;
- }
- }
- if (ad->param.mem_map_handle == 0) {
- pr_err("DTS_EAGLE_ASM - %s: mem map handle not found\n",
- __func__);
- rc = -EINVAL;
- goto fail_cmd;
- }
- /* check for integer overflow */
- if (size > (UINT_MAX - APR_CMD_OB_HDR_SZ))
- rc = -EINVAL;
- if ((rc < 0) || (size + APR_CMD_OB_HDR_SZ > po->size)) {
- pr_err("DTS_EAGLE_ASM - %s: ion alloc of size %zu too small for size requested %u\n",
- __func__, po->size, size + APR_CMD_OB_HDR_SZ);
- rc = -EINVAL;
- goto fail_cmd;
- }
- ob_params = (int *)po->kvaddr;
- *ob_params++ = m_id;
- *ob_params++ = param_id;
- *ob_params++ = size;
- generic_get_data->is_inband = 0;
- } else {
- pr_debug("DTS_EAGLE_ASM - %s: using in band\n", __func__);
- generic_get_data->is_inband = 1;
- }
-
- rc = apr_send_pkt(ac->apr, (uint32_t *)ad);
- if (rc < 0) {
- pr_err("DTS_EAGLE_ASM - %s: Commmand 0x%x failed\n", __func__,
- ad->hdr.opcode);
- goto fail_cmd;
- }
-
- rc = wait_event_timeout(ac->cmd_wait,
- (atomic_read(&ac->cmd_state) <= 0), 1*HZ);
- if (!rc) {
- pr_err("DTS_EAGLE_ASM - %s: timeout in get\n",
- __func__);
- rc = -EINVAL;
- goto fail_cmd;
- }
-
- if (generic_get_data->valid) {
- rc = 0;
- memcpy(data, po ? ob_params : generic_get_data->ints, size);
- } else {
- rc = -EINVAL;
- pr_err("DTS_EAGLE_ASM - %s: EAGLE get params problem getting data - check callback error value\n",
- __func__);
- }
-fail_cmd:
- kfree(ad);
- kfree(generic_get_data);
- generic_get_data = NULL;
- return rc;
-}
-
static int __q6asm_set_volume(struct audio_client *ac, int volume, int instance)
{
struct asm_volume_ctrl_master_gain vol;
diff --git a/sound/soc/msm/qdsp6v2/q6core.c b/sound/soc/msm/qdsp6v2/q6core.c
index c149c0257a1..4948bef90c9 100644
--- a/sound/soc/msm/qdsp6v2/q6core.c
+++ b/sound/soc/msm/qdsp6v2/q6core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -187,7 +187,7 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv)
generic_get_data->valid = 1;
generic_get_data->size_in_ints =
data->payload_size/sizeof(int);
- pr_debug("DTS_EAGLE_CORE callback size = %i\n",
+ pr_debug("callback size = %i\n",
data->payload_size);
memcpy(generic_get_data->ints, data->payload,
data->payload_size);
@@ -420,115 +420,6 @@ fail_cmd:
return ret;
}
-int core_dts_eagle_set(int size, char *data)
-{
- struct adsp_dts_eagle *payload = NULL;
- int rc = 0, size_aligned4byte;
-
- pr_debug("DTS_EAGLE_CORE - %s\n", __func__);
- if (size <= 0 || !data) {
- pr_err("DTS_EAGLE_CORE - %s: invalid size %i or pointer %pK.\n",
- __func__, size, data);
- return -EINVAL;
- }
-
- size_aligned4byte = (size+3) & 0xFFFFFFFC;
- ocm_core_open();
- if (q6core_lcl.core_handle_q) {
- payload = kzalloc(sizeof(struct adsp_dts_eagle) +
- size_aligned4byte, GFP_KERNEL);
- if (!payload) {
- pr_err("DTS_EAGLE_CORE - %s: out of memory (aligned size %i).\n",
- __func__, size_aligned4byte);
- return -ENOMEM;
- }
- payload->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_EVENT,
- APR_HDR_LEN(APR_HDR_SIZE),
- APR_PKT_VER);
- payload->hdr.pkt_size = sizeof(struct adsp_dts_eagle) +
- size_aligned4byte;
- payload->hdr.src_port = 0;
- payload->hdr.dest_port = 0;
- payload->hdr.token = 0;
- payload->hdr.opcode = ADSP_CMD_SET_DTS_EAGLE_DATA_ID;
- payload->id = DTS_EAGLE_LICENSE_ID;
- payload->overwrite = 1;
- payload->size = size;
- memcpy(payload->data, data, size);
- rc = apr_send_pkt(q6core_lcl.core_handle_q,
- (uint32_t *)payload);
- if (rc < 0) {
- pr_err("DTS_EAGLE_CORE - %s: failed op[0x%x]rc[%d]\n",
- __func__, payload->hdr.opcode, rc);
- }
- kfree(payload);
- }
- return rc;
-}
-
-int core_dts_eagle_get(int id, int size, char *data)
-{
- struct apr_hdr ah;
- int rc = 0;
-
- pr_debug("DTS_EAGLE_CORE - %s\n", __func__);
- if (size <= 0 || !data) {
- pr_err("DTS_EAGLE_CORE - %s: invalid size %i or pointer %pK.\n",
- __func__, size, data);
- return -EINVAL;
- }
- ocm_core_open();
- if (q6core_lcl.core_handle_q) {
- ah.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_EVENT,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- ah.pkt_size = sizeof(struct apr_hdr);
- ah.src_port = 0;
- ah.dest_port = 0;
- ah.token = 0;
- ah.opcode = id;
-
- q6core_lcl.bus_bw_resp_received = 0;
- generic_get_data = kzalloc(sizeof(struct generic_get_data_)
- + size, GFP_KERNEL);
- if (!generic_get_data) {
- pr_err("DTS_EAGLE_CORE - %s: error allocating memory of size %i\n",
- __func__, size);
- return -ENOMEM;
- }
-
- rc = apr_send_pkt(q6core_lcl.core_handle_q,
- (uint32_t *)&ah);
- if (rc < 0) {
- pr_err("DTS_EAGLE_CORE - %s: failed op[0x%x]rc[%d]\n",
- __func__, ah.opcode, rc);
- goto fail_cmd_2;
- }
-
- rc = wait_event_timeout(q6core_lcl.bus_bw_req_wait,
- (q6core_lcl.bus_bw_resp_received == 1),
- msecs_to_jiffies(TIMEOUT_MS));
- if (!rc) {
- pr_err("DTS_EAGLE_CORE - %s: EAGLE get params timed out\n",
- __func__);
- rc = -EINVAL;
- goto fail_cmd_2;
- }
- if (generic_get_data->valid) {
- rc = 0;
- memcpy(data, generic_get_data->ints, size);
- } else {
- rc = -EINVAL;
- pr_err("DTS_EAGLE_CORE - %s: EAGLE get params problem getting data - check callback error value\n",
- __func__);
- }
- }
-
-fail_cmd_2:
- kfree(generic_get_data);
- generic_get_data = NULL;
- return rc;
-}
-
uint32_t core_set_dolby_manufacturer_id(int manufacturer_id)
{
struct adsp_dolby_manufacturer_id payload;
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index 123d347881f..bec8016937a 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -246,9 +246,8 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
SND_SOC_DAPM_STREAM_STOP);
} else {
rtd->pop_wait = 1;
- queue_delayed_work(system_power_efficient_wq,
- &rtd->delayed_work,
- msecs_to_jiffies(rtd->pmdown_time));
+ schedule_delayed_work(&rtd->delayed_work,
+ msecs_to_jiffies(rtd->pmdown_time));
}
} else {
/* capture streams can be powered down now */
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index b7973e494fa..52f0cc8d4e3 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -65,6 +65,7 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
struct snd_soc_codec *codec;
struct snd_soc_dapm_context *dapm;
struct snd_soc_jack_pin *pin;
+ unsigned int sync = 0;
int enable;
trace_snd_soc_jack_report(jack, mask, status);
@@ -92,12 +93,16 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
snd_soc_dapm_enable_pin(dapm, pin->pin);
else
snd_soc_dapm_disable_pin(dapm, pin->pin);
+
+ /* we need to sync for this case only */
+ sync = 1;
}
/* Report before the DAPM sync to help users updating micbias status */
blocking_notifier_call_chain(&jack->notifier, jack->status, jack);
- snd_soc_dapm_sync(dapm);
+ if (sync)
+ snd_soc_dapm_sync(dapm);
snd_jack_report(jack->jack, jack->status);
@@ -280,7 +285,7 @@ static irqreturn_t gpio_handler(int irq, void *data)
if (device_may_wakeup(dev))
pm_wakeup_event(dev, gpio->debounce_time + 50);
- queue_delayed_work(system_power_efficient_wq, &gpio->work,
+ schedule_delayed_work(&gpio->work,
msecs_to_jiffies(gpio->debounce_time));
return IRQ_HANDLED;
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 3e62ac821f0..d7c78e47788 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -417,9 +417,8 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
} else {
/* start delayed pop wq here for playback streams */
rtd->pop_wait = 1;
- queue_delayed_work(system_power_efficient_wq,
- &rtd->delayed_work,
- msecs_to_jiffies(rtd->pmdown_time));
+ schedule_delayed_work(&rtd->delayed_work,
+ msecs_to_jiffies(rtd->pmdown_time));
}
}
diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c
index bbc782e364b..9118fb8cc10 100644
--- a/tools/perf/ui/browser.c
+++ b/tools/perf/ui/browser.c
@@ -672,7 +672,7 @@ static void __ui_browser__line_arrow_down(struct ui_browser *browser,
ui_browser__gotorc(browser, row, column + 1);
SLsmg_draw_hline(2);
- if (row++ == 0)
+ if (++row == 0)
goto out;
} else
row = 0;